# Backend & Frontend Integration Guide

## Overview

This guide explains how to integrate the React frontend with the Express.js backend securely.

## Architecture

```
┌─────────────────────────────────────────────────────────┐
│           FRONTEND (React)                              │
│     - Authentication State                              │
│     - Token Management                                  │
│     - CSRF Token Handling                               │
│     - User Preferences                                  │
└──────────────────┬──────────────────────────────────────┘
                   │ HTTPS
        ┌──────────┴──────────┐
        │                     │
   JSON/REST API      WebSocket (future)
        │                     │
┌──────────────────┬──────────────────────────────────────┐
│           BACKEND (Express.js)                           │
│     - JWT Authentication                                │
│     - Password Hashing                                  │
│     - CSRF Validation                                   │
│     - Rate Limiting                                     │
│     - Audit Logging                                     │
│     - 2FA Management                                    │
└──────────────────┬──────────────────────────────────────┘
                   │
        ┌──────────┴──────────┐
        │                     │
    PostgreSQL          Redis Cache
    Database           (optional)
```

## Authentication Flow

### 1. User Registration

**Frontend:**
```javascript
const response = await fetch('http://localhost:5000/api/v1/auth/register', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    firstName: 'John',
    lastName: 'Doe',
    email: 'john@example.com',
    password: 'SecurePassword123!@#',
    passwordConfirm: 'SecurePassword123!@#',
    termsAccepted: true,
  }),
});

const data = await response.json();
if (data.success) {
  // Show success toast
  // Redirect to login
}
```

**Backend:**
1. Validates input (express-validator)
2. Checks password strength
3. Checks if email already exists
4. Hashes password with bcryptjs (12 rounds)
5. Creates user in database
6. Logs USER_REGISTER audit event
7. Returns user data

### 2. User Login

**Frontend:**
```javascript
const response = await fetch('http://localhost:5000/api/v1/auth/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-CSRF-Token': csrfToken, // Get from previous response
  },
  credentials: 'include', // Send cookies if set
  body: JSON.stringify({
    email: 'john@example.com',
    password: 'SecurePassword123!@#',
    rememberMe: true,
  }),
});

const data = await response.json();

if (data.requiresTwoFA) {
  // Redirect to 2FA verification page
  // Store tempToken
} else if (data.success) {
  // Store tokens
  localStorage.setItem('accessToken', data.accessToken);
  localStorage.setItem('refreshToken', data.refreshToken);
  
  // Set Redux/Context state
  // Redirect to dashboard
}
```

**Backend:**
1. Finds user by email
2. Verifies password with bcryptjs
3. Checks if user is banned/active
4. If 2FA enabled, returns tempToken (2FA required)
5. Otherwise, generates JWT token pair
6. Creates session in database
7. Returns accessToken + refreshToken
8. Logs USER_LOGIN audit event

### 3. Request with JWT Token

**Frontend:**
```javascript
const headers = {
  'Authorization': `Bearer ${accessToken}`,
  'X-CSRF-Token': csrfToken,
  'Content-Type': 'application/json',
};

const response = await fetch('http://localhost:5000/api/v1/users/me', {
  method: 'GET',
  headers,
  credentials: 'include',
});
```

**Backend:**
1. Extracts token from Authorization header
2. Verifies JWT signature and expiration
3. Attaches user data to request (req.user)
4. Processes request
5. Returns response with new X-CSRF-Token header

### 4. Token Refresh

**Frontend:**
```javascript
// When access token expires (401 response)
const response = await fetch('http://localhost:5000/api/v1/auth/refresh', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    refreshToken: localStorage.getItem('refreshToken'),
  }),
});

const data = await response.json();
if (data.success) {
  localStorage.setItem('accessToken', data.accessToken);
  // Retry original request
} else {
  // Redirect to login
}
```

**Backend:**
1. Verifies refresh token
2. Looks up user
3. Generates new access token
4. Returns new accessToken

### 5. 2FA Verification

**Frontend:**
```javascript
// After getting tempToken from login
const response = await fetch('http://localhost:5000/api/v1/auth/2fa/verify', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${tempToken}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    code: '123456', // From TOTP app
  }),
});

const data = await response.json();
if (data.success) {
  // Use accessToken for future requests
  localStorage.setItem('accessToken', data.accessToken);
}
```

**Backend:**
1. Verifies 2FA code with TOTP (speakeasy)
2. Generates full access token
3. Returns accessToken

## CSRF Token Handling

**Pattern:**
1. Every successful request includes `X-CSRF-Token` in response header
2. Frontend stores this token
3. For state-changing requests (POST, PUT, DELETE), include token in `X-CSRF-Token` header
4. Backend validates token matches user session
5. Token is invalidated after single use (automatic rotation)

**Example:**

```javascript
// Assume csrfToken from previous response
const response = await fetch('http://localhost:5000/api/v1/users/me/profile', {
  method: 'PATCH',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'X-CSRF-Token': csrfToken,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    firstName: 'Jane',
    bio: 'New bio',
  }),
});
```

## API Error Handling

**Frontend:**
```javascript
async function apiCall(endpoint, options = {}) {
  try {
    const response = await fetch(`http://localhost:5000/api/v1${endpoint}`, {
      headers: {
        'Authorization': `Bearer ${getAccessToken()}`,
        'X-CSRF-Token': getCsrfToken(),
        ...options.headers,
      },
      ...options,
    });

    if (response.status === 401) {
      // Try to refresh token
      const refreshed = await refreshAccessToken();
      if (refreshed) {
        // Retry request
        return apiCall(endpoint, options);
      } else {
        // Redirect to login
        redirectToLogin();
      }
    }

    if (response.status === 429) {
      // Rate limited
      const retryAfter = response.headers.get('Retry-After');
      showError(`Too many requests. Please wait ${retryAfter} seconds.`);
      return null;
    }

    const data = await response.json();

    if (!data.success) {
      throw new Error(data.error.message);
    }

    return data;
  } catch (error) {
    console.error('API call failed:', error);
    throw error;
  }
}
```

## State Management Example (Redux)

### Auth Slice
```javascript
// store/authSlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';

export const login = createAsyncThunk(
  'auth/login',
  async ({ email, password }, { rejectWithValue }) => {
    try {
      const response = await fetch('http://localhost:5000/api/v1/auth/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email, password }),
      });

      const data = await response.json();
      
      if (!data.success) {
        return rejectWithValue(data.error.message);
      }

      localStorage.setItem('accessToken', data.accessToken);
      localStorage.setItem('refreshToken', data.refreshToken);

      return data;
    } catch (error) {
      return rejectWithValue(error.message);
    }
  }
);

const authSlice = createSlice({
  name: 'auth',
  initialState: {
    user: null,
    accessToken: localStorage.getItem('accessToken'),
    loading: false,
    error: null,
  },
  extraReducers: (builder) => {
    builder
      .addCase(login.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(login.fulfilled, (state, action) => {
        state.loading = false;
        state.user = action.payload.user;
        state.accessToken = action.payload.accessToken;
      })
      .addCase(login.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload;
      });
  },
});

export default authSlice.reducer;
```

## Development Workflow

### 1. Start Both Servers

```bash
# Terminal 1: Backend
cd backend
npm run dev

# Terminal 2: Frontend
cd ..
npm start
```

### 2. Debug API Calls

```javascript
// Add to frontend code
const originalFetch = window.fetch;
window.fetch = function(...args) {
  console.log('API Call:', args[0], args[1]);
  return originalFetch.apply(this, args)
    .then(r => {
      console.log('Response:', r.status, r.statusText);
      return r;
    });
};
```

### 3. Monitor Backend Logs

```bash
# Backend logs
tail -f backend/logs/app.log
tail -f backend/logs/error.log
tail -f backend/logs/audit.log
```

### 4. Test Database

```bash
# Connect to database
psql -U postgres -d serdark_db

# Check recent audit logs
SELECT event_type, action, user_id, created_at 
FROM audit_logs 
ORDER BY created_at DESC 
LIMIT 10;
```

## Production Deployment

### Environment Variables

Ensure these are set on production server:

```bash
# Linux/Mac
export NODE_ENV=production
export JWT_SECRET=your-random-32-char-secret
export JWT_REFRESH_SECRET=your-random-32-char-secret
export DB_HOST=your-db-host
export FRONTEND_URL=https://serdark.digital
export CORS_ORIGIN=https://serdark.digital
export HTTPS_ENABLED=true
```

### HTTPS/TLS

```nginx
# nginx configuration example
server {
    listen 443 ssl http2;
    server_name api.serdark.digital;

    ssl_certificate /etc/ssl/certs/cert.pem;
    ssl_certificate_key /etc/ssl/private/key.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
        proxy_pass http://localhost:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
```

### Frontend CORS Configuration

```javascript
// In React app, update API base URL for production
const API_URL = process.env.NODE_ENV === 'production' 
  ? 'https://api.serdark.digital/api/v1'
  : 'http://localhost:5000/api/v1';
```

## Security Checklist

- [x] JWT tokens expire after 24 hours
- [x] Refresh tokens expire after 7 days
- [x] Passwords hashed with bcryptjs (12+ rounds)
- [x] Rate limiting on sensitive endpoints
- [x] CSRF tokens for state-changing requests
- [x] Input validation on all endpoints
- [x] SQL injection prevention (parameterized queries)
- [x] Comprehensive audit logging
- [x] 2FA framework ready
- [x] Session management
- [x] Helmet.js security headers
- [x] CORS configured
- [ ] HTTPS enforced in production
- [ ] Database encryption at rest
- [ ] Secrets manager (HashiCorp Vault)
- [ ] WAF configuration
- [ ] DDoS protection

## Monitoring

### Health Endpoints

```bash
# Frontend health
curl http://localhost:3000/health

# Backend health
curl http://localhost:5000/health

# Backend readiness
curl http://localhost:5000/ready
```

### Metrics to Monitor

- Average response time
- Error rate (500 errors)
- Database query time
- Login failure rate
- Rate limit violations
- Audit log events
- Active sessions count
- Memory usage
- CPU usage

## Support & Troubleshooting

### Common Issues

**CORS errors:**
- Check CORS_ORIGIN in backend .env
- Ensure frontend URL matches exactly

**401 Unauthorized:**
- Token expired - call refresh endpoint
- Token invalid - re-authenticate user

**429 Rate Limited:**
- Wait Retry-After seconds before retrying
- Check rate limit configuration

**Database connection error:**
- Verify PostgreSQL is running
- Check DB credentials in .env

For more help, see [Backend Setup](./BACKEND_SETUP.md) and [API Documentation](./API_DOCUMENTATION.md).
