# IP Detection Guide for Adminify Activity Logs

## Overview

The Adminify Activity Logs plugin includes robust IP address detection that works correctly in various hosting environments including local development, shared hosting, VPS, dedicated servers, and sites behind CDNs/proxies like CloudFlare.

## How IP Detection Works

### Detection Priority Order

The plugin checks for IP addresses in the following order (from most to least reliable):

1. **HTTP_CF_CONNECTING_IP** - CloudFlare's header for the real visitor IP
2. **HTTP_TRUE_CLIENT_IP** - CloudFlare Enterprise header
3. **HTTP_X_REAL_IP** - Nginx proxy/real IP header
4. **HTTP_CLIENT_IP** - General proxy header
5. **HTTP_X_FORWARDED_FOR** - Standard header used by load balancers and proxies
6. **HTTP_X_FORWARDED** - Alternative forwarded header
7. **HTTP_X_CLUSTER_CLIENT_IP** - Used in cluster environments
8. **HTTP_FORWARDED_FOR** - Alternative forwarded header
9. **HTTP_FORWARDED** - Standard forwarded header
10. **REMOTE_ADDR** - Direct connection IP (fallback)

### Special Handling

The plugin automatically handles:

- **IPv6 localhost (::1)** - Converts to 127.0.0.1 for consistency
- **IPv4-mapped IPv6 addresses** - Extracts the IPv4 address (e.g., ::ffff:192.168.1.1 becomes 192.168.1.1)
- **Comma-separated IP lists** - Takes the first valid IP (common with X-Forwarded-For)
- **Local development** - Shows 127.0.0.1 instead of ::1

## Production Environment Considerations

### CloudFlare Users

If your site uses CloudFlare, the plugin will automatically detect and use the real visitor IP from CloudFlare's headers. No configuration needed.

### Custom Proxy/CDN Setup

If you're using a custom proxy or CDN setup, you can customize the IP detection using WordPress filters:

#### Example 1: Prioritize a Custom Header

```php
add_filter( 'adminify_activity_logs_ip_headers', function( $headers ) {
    // Add your custom header at the beginning for highest priority
    array_unshift( $headers, 'HTTP_MY_CUSTOM_IP_HEADER' );
    return $headers;
});
```

#### Example 2: Use Only Specific Headers

```php
add_filter( 'adminify_activity_logs_ip_headers', function( $headers ) {
    // Only trust CloudFlare and REMOTE_ADDR
    return [
        'HTTP_CF_CONNECTING_IP',
        'REMOTE_ADDR'
    ];
});
```

#### Example 3: Override Detected IP

```php
add_filter( 'adminify_activity_logs_detected_ip', function( $ip, $headers ) {
    // Custom logic to determine the real IP
    if ( isset( $_SERVER['HTTP_X_MY_REAL_IP'] ) ) {
        return sanitize_text_field( $_SERVER['HTTP_X_MY_REAL_IP'] );
    }
    return $ip;
}, 10, 2 );
```

## Security Considerations

### IP Spoofing Prevention

Be aware that headers like `X-Forwarded-For` can be spoofed by clients if not properly configured at the proxy level. Only trust headers that are set by your infrastructure:

- If using CloudFlare, trust `HTTP_CF_CONNECTING_IP`
- If using AWS ALB, trust `HTTP_X_FORWARDED_FOR`
- If using Nginx as reverse proxy, ensure `X-Real-IP` is properly configured

### Private IP Filtering

The plugin includes commented code to filter out private/reserved IP ranges. To enable this (useful if you want to ignore internal network IPs):

Edit `/Inc/ActivityLogs/Inc/Api.php` and uncomment the validation in the `is_valid_ip()` method:

```php
// Check if it's not a private or reserved IP
if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) === false ) {
    // Allow localhost IPs
    if ( $ip !== '127.0.0.1' && $ip !== '::1' ) {
        return false;
    }
}
```

## Troubleshooting

### All IPs Show as 127.0.0.1

This usually means the plugin cannot detect any valid IP. Check:
1. Your server configuration
2. Whether you're behind a proxy/CDN that's not passing headers
3. PHP configuration (some hosts disable certain $_SERVER variables)

### IPs Show Server's IP Instead of Visitor's

This happens when:
1. The site is behind a proxy/CDN but the appropriate headers aren't being passed
2. The proxy headers aren't trusted

Solution: Add the appropriate header to the detection priority using the filter shown above.

### Testing IP Detection

You can test IP detection by adding this to your theme's functions.php temporarily:

```php
add_action( 'admin_notices', function() {
    if ( current_user_can( 'manage_options' ) ) {
        $api = new \JLTAdminify\Modules\ActivityLogs\Inc\ActivityLogs\Inc\Api();
        $reflection = new ReflectionClass( $api );
        $method = $reflection->getMethod( 'get_ip_address' );
        $method->setAccessible( true );
        $detected_ip = $method->invoke( $api );

        echo '<div class="notice notice-info"><p>Detected IP: ' . esc_html( $detected_ip ) . '</p></div>';
    }
});
```

## Common Hosting Scenarios

### Shared Hosting
Usually works out of the box with REMOTE_ADDR.

### VPS/Dedicated with Nginx
Configure Nginx to pass the real IP:
```nginx
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
```

### Docker/Kubernetes
May need custom configuration depending on ingress controller. Often uses X-Forwarded-For or X-Real-IP.

### AWS/Google Cloud/Azure
- AWS ALB: Uses X-Forwarded-For
- Google Cloud LB: Uses X-Forwarded-For
- Azure Application Gateway: Uses X-Forwarded-For

## Support

If you're having issues with IP detection in your specific environment, please provide:
1. Your hosting environment (shared, VPS, cloud provider, etc.)
2. Whether you're using a CDN/proxy (CloudFlare, custom, etc.)
3. The headers your server receives (check phpinfo() output)