# CORS Management Documentation

## Overview

This API now includes comprehensive CORS (Cross-Origin Resource Sharing) management. CORS allows your API to be accessed from web applications hosted on different domains.

## How It Works

### Automatic CORS Header Application

All API responses automatically include CORS headers when CORS is enabled. This allows web applications from configured origins to access your API.

### Preflight Request Handling

The API automatically handles preflight OPTIONS requests (sent by browsers before actual requests to CORS-protected resources). These are handled with a 204 No Content response.

### Origin Validation

Only requests from configured allowed origins are accepted. Requests from unauthorized origins are rejected.

## Configuration

Edit `config/config.php` to configure CORS:

```php
'cors' => [
    'enabled' => true,  // Enable/disable CORS
    'allowed_origins' => [
        'http://localhost:3000',
        'https://example.com',
    ],
    'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
    'allowed_headers' => ['Content-Type', 'Authorization', 'X-Requested-With', 'Accept'],
    'exposed_headers' => ['Content-Length', 'X-JSON-Response-Code'],
    'allow_credentials' => false,
    'max_age' => 86400,
],
```

## Configuration Options

| Option              | Type  | Default                                                 | Description                                                                         |
| ------------------- | ----- | ------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| `enabled`           | bool  | `true`                                                  | Enable or disable CORS                                                              |
| `allowed_origins`   | array | `[]`                                                    | List of domains allowed to access the API. Use `'*'` to allow all (NOT recommended) |
| `allowed_methods`   | array | `GET, POST, PUT, DELETE, PATCH, OPTIONS`                | HTTP methods allowed                                                                |
| `allowed_headers`   | array | `Content-Type, Authorization, X-Requested-With, Accept` | Headers allowed in requests                                                         |
| `exposed_headers`   | array | `Content-Length, X-JSON-Response-Code`                  | Headers exposed to the client                                                       |
| `allow_credentials` | bool  | `false`                                                 | Allow credentials (cookies, auth) in requests                                       |
| `max_age`           | int   | `86400`                                                 | Browser cache time for preflight (seconds)                                          |

## Setup for Different Environments

### Development

```php
'cors' => [
    'enabled' => true,
    'allowed_origins' => [
        'http://localhost:3000',
        'http://localhost:8080',
        'http://127.0.0.1:3000',
    ],
    'allow_credentials' => false,
    'max_age' => 3600,
],
```

### Production

```php
'cors' => [
    'enabled' => true,
    'allowed_origins' => [
        'https://app.example.com',
        'https://admin.example.com',
    ],
    'allow_credentials' => false,
    'max_age' => 86400,
],
```

### Allow All Origins (NOT RECOMMENDED for Production)

```php
'cors' => [
    'enabled' => true,
    'allowed_origins' => ['*'],
    'allow_credentials' => false,
],
```

## Browser Preflight Requests

When making cross-origin requests with certain headers or methods (like PUT or DELETE), browsers automatically send a preflight OPTIONS request. The API handles these automatically:

```text
Browser sends: OPTIONS /api/resource
API responds: 204 No Content + CORS headers
Browser sees: Request is allowed, proceeds with actual request
```

## Testing CORS

### Using curl

```bash
# Test CORS with curl
curl -H "Origin: http://localhost:3000" \
     -H "Access-Control-Request-Method: POST" \
     -H "Access-Control-Request-Headers: Content-Type" \
     -X OPTIONS \
     http://localhost:8000/api/users/index -v
```

### Expected Response Headers

```text
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, Accept
Access-Control-Max-Age: 86400
```

## Security Considerations

1. **Be Specific with Origins**: Always specify exact allowed origins. Don't use `'*'` in production unless absolutely necessary.

2. **Credentials**: Only set `allow_credentials: true` if you understand the security implications. This allows cross-origin requests to send cookies.

3. **Sensitive Headers**: Don't expose sensitive headers in `exposed_headers`. Only expose what clients actually need.

4. **HTTPS in Production**: Always use HTTPS in production to prevent man-in-the-middle attacks.

## CorsManager Class

The `CorsManager` class handles all CORS logic. You can also use it programmatically:

```php
$corsManager = $container->make(\Api\Core\CorsManager::class);

// Check if current request is allowed
if ($corsManager->isOriginAllowed()) {
    // Process request
}

// Apply CORS headers manually
$corsManager->applyHeaders();

// Check for preflight request
if ($corsManager->isPreflightRequest()) {
    $corsManager->handlePreflight();
}
```

## Troubleshooting

### Preflight request fails

- Check that the origin in the request matches one in `allowed_origins`
- Verify CORS is enabled in config
- Check browser console for CORS error messages

### Missing CORS headers in response

- Ensure CORS is enabled: `'enabled' => true`
- Verify the requesting origin is in `allowed_origins`
- Check that `CorsManager` is properly initialized in the container

### "No Access-Control-Allow-Origin header"

- Browser origin is not in `allowed_origins`
- Add the origin or use `'*'` (only for development)

## References

- [MDN: CORS Documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
- [OWASP: CORS](https://owasp.org/www-community/CORS)
