Fix public client IP extraction and hide duplicate footer creation date
- Enhance RequestLogger::getClientIp() with 2-pass detection prioritizing public IPs over proxy/internal IPs - Hide footer creation date when identical to modification date to prevent duplicate date display - Improve AdminAuth log helper and footer template tooltips
This commit is contained in:
@@ -304,14 +304,13 @@ class AdminAuth
|
|||||||
mkdir($dir, 0755, true);
|
mkdir($dir, 0755, true);
|
||||||
}
|
}
|
||||||
$timestamp = date('Y-m-d H:i:s');
|
$timestamp = date('Y-m-d H:i:s');
|
||||||
if (class_exists('RequestLogger')) {
|
if (!class_exists('RequestLogger')) {
|
||||||
$ip = RequestLogger::getClientIp();
|
$loggerClass = __DIR__ . '/../../cms/core/class/RequestLogger.php';
|
||||||
} else {
|
if (file_exists($loggerClass)) {
|
||||||
$ip = $_SERVER['HTTP_CF_CONNECTING_IP'] ?? $_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? 'cli';
|
require_once $loggerClass;
|
||||||
if (($commaPos = strpos($ip, ',')) !== false) {
|
|
||||||
$ip = trim(substr($ip, 0, $commaPos));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$ip = class_exists('RequestLogger') ? RequestLogger::getClientIp() : ($_SERVER['REMOTE_ADDR'] ?? '127.0.0.1');
|
||||||
file_put_contents($logFile, "[{$timestamp}] [{$level}] [{$ip}] {$message}\n", FILE_APPEND);
|
file_put_contents($logFile, "[{$timestamp}] [{$level}] [{$ip}] {$message}\n", FILE_APPEND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -478,9 +478,13 @@ class CodePressCMS {
|
|||||||
$created = date('d-m-Y H:i', $createdTimestamp);
|
$created = date('d-m-Y H:i', $createdTimestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show created date only if it is distinctly different from modified date
|
||||||
|
$showCreated = ($created !== $modified);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'created' => $created,
|
'created' => $created,
|
||||||
'modified' => $modified,
|
'modified' => $modified,
|
||||||
|
'show_created' => $showCreated,
|
||||||
'size' => $this->formatFileSize($stats['size'])
|
'size' => $this->formatFileSize($stats['size'])
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -1151,10 +1155,12 @@ class CodePressCMS {
|
|||||||
if (isset($page['file_info'])) {
|
if (isset($page['file_info'])) {
|
||||||
$templateData['created'] = htmlspecialchars($page['file_info']['created']);
|
$templateData['created'] = htmlspecialchars($page['file_info']['created']);
|
||||||
$templateData['modified'] = htmlspecialchars($page['file_info']['modified']);
|
$templateData['modified'] = htmlspecialchars($page['file_info']['modified']);
|
||||||
|
$templateData['show_created'] = !empty($page['file_info']['show_created']);
|
||||||
$templateData['file_info_block'] = true;
|
$templateData['file_info_block'] = true;
|
||||||
} else {
|
} else {
|
||||||
$templateData['created'] = '';
|
$templateData['created'] = '';
|
||||||
$templateData['modified'] = '';
|
$templateData['modified'] = '';
|
||||||
|
$templateData['show_created'] = false;
|
||||||
$templateData['file_info_block'] = false;
|
$templateData['file_info_block'] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,29 +25,48 @@ class RequestLogger
|
|||||||
|
|
||||||
public static function getClientIp(): string
|
public static function getClientIp(): string
|
||||||
{
|
{
|
||||||
$headers = [
|
$headerKeys = [
|
||||||
'HTTP_CF_CONNECTING_IP',
|
'HTTP_CF_CONNECTING_IP',
|
||||||
'HTTP_X_REAL_IP',
|
'HTTP_X_REAL_IP',
|
||||||
'HTTP_CLIENT_IP',
|
'HTTP_CLIENT_IP',
|
||||||
'HTTP_X_FORWARDED_FOR',
|
'HTTP_X_FORWARDED_FOR',
|
||||||
|
'HTTP_X_FORWARDED',
|
||||||
|
'HTTP_FORWARDED_FOR',
|
||||||
|
'HTTP_FORWARDED',
|
||||||
'REMOTE_ADDR',
|
'REMOTE_ADDR',
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($headers as $header) {
|
// Pass 1: Prioritize valid PUBLIC IP addresses (skips 127.0.0.1, 10.x, 172.x, 192.168.x proxy/internal IPs)
|
||||||
if (!empty($_SERVER[$header])) {
|
foreach ($headerKeys as $key) {
|
||||||
$rawIp = $_SERVER[$header];
|
if (empty($_SERVER[$key])) continue;
|
||||||
if (str_contains($rawIp, ',')) {
|
|
||||||
$ips = explode(',', $rawIp);
|
$value = $_SERVER[$key];
|
||||||
$rawIp = trim($ips[0]);
|
$ips = str_contains($value, ',') ? explode(',', $value) : [$value];
|
||||||
}
|
|
||||||
$rawIp = trim($rawIp);
|
foreach ($ips as $rawIp) {
|
||||||
if (filter_var($rawIp, FILTER_VALIDATE_IP) !== false) {
|
$ip = trim($rawIp);
|
||||||
return $rawIp;
|
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {
|
||||||
|
return $ip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $_SERVER['REMOTE_ADDR'] ?? 'cli';
|
// Pass 2: Fallback for local development environments
|
||||||
|
foreach ($headerKeys as $key) {
|
||||||
|
if (empty($_SERVER[$key])) continue;
|
||||||
|
|
||||||
|
$value = $_SERVER[$key];
|
||||||
|
$ips = str_contains($value, ',') ? explode(',', $value) : [$value];
|
||||||
|
|
||||||
|
foreach ($ips as $rawIp) {
|
||||||
|
$ip = trim($rawIp);
|
||||||
|
if (filter_var($ip, FILTER_VALIDATE_IP) !== false) {
|
||||||
|
return $ip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function detectVisitorInfo(string $ua, string $user = ''): array
|
public static function detectVisitorInfo(string $ua, string $user = ''): array
|
||||||
|
|||||||
@@ -9,10 +9,12 @@
|
|||||||
<span class="page-title d-none d-lg-inline" title="{{page_title}}">{{page_title}}</span>
|
<span class="page-title d-none d-lg-inline" title="{{page_title}}">{{page_title}}</span>
|
||||||
{{#file_info_block}}
|
{{#file_info_block}}
|
||||||
<span class="ms-2">
|
<span class="ms-2">
|
||||||
|
{{#show_created}}
|
||||||
<i class="bi bi-calendar-plus footer-icon" title="{{t_created}}: {{created}}"></i>
|
<i class="bi bi-calendar-plus footer-icon" title="{{t_created}}: {{created}}"></i>
|
||||||
<span class="file-created">{{created}}</span>
|
<span class="file-created me-1" title="{{t_created}}: {{created}}">{{created}}</span>
|
||||||
<i class="bi bi-calendar-check ms-1 footer-icon" title="{{t_modified}}: {{modified}}"></i>
|
{{/show_created}}
|
||||||
<span class="file-modified">{{modified}}</span>
|
<i class="bi bi-calendar-check footer-icon" title="{{t_modified}}: {{modified}}"></i>
|
||||||
|
<span class="file-modified" title="{{t_modified}}: {{modified}}">{{modified}}</span>
|
||||||
</span>
|
</span>
|
||||||
{{/file_info_block}}
|
{{/file_info_block}}
|
||||||
</small>
|
</small>
|
||||||
|
|||||||
Reference in New Issue
Block a user