TKK_E32230273/api_login_history.php

151 lines
5.9 KiB
PHP

<?php
if (session_status() === PHP_SESSION_NONE) session_start();
header('Content-Type: application/json');
if (!isset($_SESSION['user_id'])) {
echo json_encode(['success' => false, 'message' => 'Unauthorized']);
exit;
}
include 'koneksi.php';
function getDeviceDetail($ua) {
$detail = ['type' => 'Unknown', 'brand' => '', 'os' => ''];
$uaLower = strtolower($ua);
// Detect OS
if (strpos($uaLower, 'windows nt 10') !== false) {
$detail['os'] = 'Windows 10/11';
$detail['type'] = 'Windows PC';
} elseif (strpos($uaLower, 'windows nt 6.3') !== false) {
$detail['os'] = 'Windows 8.1';
$detail['type'] = 'Windows PC';
} elseif (strpos($uaLower, 'windows nt 6.1') !== false) {
$detail['os'] = 'Windows 7';
$detail['type'] = 'Windows PC';
} elseif (strpos($uaLower, 'windows') !== false) {
$detail['os'] = 'Windows';
$detail['type'] = 'Windows PC';
} elseif (strpos($uaLower, 'macintosh') !== false || strpos($uaLower, 'mac os x') !== false) {
// Extract macOS version
if (preg_match('/mac os x (\d+[\._]\d+[\._]?\d*)/i', $ua, $m)) {
$ver = str_replace('_', '.', $m[1]);
$detail['os'] = 'macOS ' . $ver;
} else {
$detail['os'] = 'macOS';
}
$detail['type'] = 'Mac';
$detail['brand'] = 'Apple';
} elseif (strpos($uaLower, 'iphone') !== false) {
$detail['type'] = 'iPhone';
$detail['brand'] = 'Apple';
if (preg_match('/iphone os (\d+[\._]\d+)/i', $ua, $m)) {
$detail['os'] = 'iOS ' . str_replace('_', '.', $m[1]);
} else {
$detail['os'] = 'iOS';
}
} elseif (strpos($uaLower, 'ipad') !== false) {
$detail['type'] = 'iPad';
$detail['brand'] = 'Apple';
if (preg_match('/cpu os (\d+[\._]\d+)/i', $ua, $m)) {
$detail['os'] = 'iPadOS ' . str_replace('_', '.', $m[1]);
} else {
$detail['os'] = 'iPadOS';
}
} elseif (strpos($uaLower, 'android') !== false) {
// Extract Android version
$androidVer = '';
if (preg_match('/android (\d+[\.\d]*)/i', $ua, $m)) {
$androidVer = $m[1];
}
$detail['os'] = 'Android' . ($androidVer ? ' ' . $androidVer : '');
// Try to detect brand/model from user agent
// Common pattern: Android X.X; BRAND MODEL Build/...
$detail['brand'] = '';
if (preg_match('/;\s*([^;)]+)\s*Build\//i', $ua, $m)) {
$model = trim($m[1]);
// Clean up common prefixes
$brandMap = [
'SM-' => 'Samsung', 'GT-' => 'Samsung', 'SAMSUNG' => 'Samsung',
'Redmi' => 'Xiaomi', 'Mi ' => 'Xiaomi', 'POCO' => 'Xiaomi POCO', 'M2' => 'Xiaomi',
'vivo' => 'Vivo', 'V2' => 'Vivo',
'OPPO' => 'OPPO', 'CPH' => 'OPPO', 'RMX' => 'Realme',
'Pixel' => 'Google Pixel', 'Nexus' => 'Google Nexus',
'HUAWEI' => 'Huawei', 'VOG' => 'Huawei', 'ELE' => 'Huawei',
'ASUS' => 'ASUS', 'Nokia' => 'Nokia', 'LG' => 'LG',
'Sony' => 'Sony', 'OnePlus' => 'OnePlus', 'IN2' => 'OnePlus',
'Infinix' => 'Infinix', 'TECNO' => 'Tecno', 'itel' => 'Itel',
];
$matched = false;
foreach ($brandMap as $prefix => $brand) {
if (stripos($model, $prefix) !== false) {
$detail['brand'] = $brand;
$detail['type'] = $model;
$matched = true;
break;
}
}
if (!$matched) {
$detail['type'] = $model;
}
} else {
$detail['type'] = 'Android Device';
}
} elseif (strpos($uaLower, 'linux') !== false) {
$detail['os'] = 'Linux';
$detail['type'] = 'Linux PC';
}
return $detail;
}
function getBrowserName($ua) {
// Order matters: check Edge before Chrome, check Chrome before Safari
if (preg_match('/Edg[e\/]?\s*(\d+[\.\d]*)/i', $ua, $m)) return 'Edge ' . intval($m[1]);
if (preg_match('/OPR\/(\d+[\.\d]*)/i', $ua, $m)) return 'Opera ' . intval($m[1]);
if (preg_match('/Chrome\/(\d+[\.\d]*)/i', $ua, $m)) return 'Chrome ' . intval($m[1]);
if (preg_match('/Firefox\/(\d+[\.\d]*)/i', $ua, $m)) return 'Firefox ' . intval($m[1]);
if (preg_match('/Version\/(\d+[\.\d]*).*Safari/i', $ua, $m)) return 'Safari ' . intval($m[1]);
if (strpos($ua, 'Safari') !== false) return 'Safari';
return 'Unknown Browser';
}
try {
$stmt = $pdo->prepare("SELECT * FROM login_history WHERE id_account = ? ORDER BY login_time DESC");
$stmt->execute([$_SESSION['user_id']]);
$logs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$result = [];
foreach ($logs as $log) {
$time = strtotime($log['login_time']);
$device = getDeviceDetail($log['device_info']);
$browser = getBrowserName($log['device_info']);
// Build display name
$deviceName = $device['type'];
if ($device['brand'] && stripos($device['type'], $device['brand']) === false) {
$deviceName = $device['brand'] . ' ' . $device['type'];
}
$isDesktop = in_array($device['type'], ['Windows PC', 'Mac', 'Linux PC']) ||
strpos(strtolower($device['os']), 'windows') !== false ||
strpos(strtolower($device['os']), 'macos') !== false ||
strpos(strtolower($device['os']), 'linux') !== false;
$result[] = [
'date' => date('d F Y', $time),
'time' => date('H:i:s', $time),
'device' => $deviceName,
'os' => $device['os'],
'browser' => $browser,
'ip' => $log['ip_address'],
'is_desktop' => $isDesktop
];
}
echo json_encode(['success' => true, 'logs' => $result]);
} catch (PDOException $e) {
echo json_encode(['success' => false, 'message' => 'Database error']);
}