add superadmin dashboard. subscriptions
This commit is contained in:
@@ -96,13 +96,146 @@ class Profile extends BaseController
|
||||
$userId = $this->getCurrentUserId();
|
||||
$user = $this->userModel->find($userId);
|
||||
|
||||
// Получаем список активных сессий
|
||||
$sessions = $this->getUserSessions($userId);
|
||||
|
||||
return $this->renderTwig('profile/security', [
|
||||
'title' => 'Безопасность',
|
||||
'user' => $user,
|
||||
'active_tab' => 'security',
|
||||
'sessions' => $sessions,
|
||||
'currentSessionId' => session_id(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение списка активных сессий пользователя
|
||||
*/
|
||||
protected function getUserSessions(int $userId): array
|
||||
{
|
||||
$db = \Config\Database::connect();
|
||||
|
||||
// Получаем сессии из таблицы ci_sessions (требует настройки DatabaseHandler)
|
||||
// Также получаем remember-токены
|
||||
$rememberTokens = $db->table('remember_tokens')
|
||||
->where('user_id', $userId)
|
||||
->where('expires_at >', date('Y-m-d H:i:s'))
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
$sessions = [];
|
||||
|
||||
// Добавляем remember-токены как сессии
|
||||
foreach ($rememberTokens as $token) {
|
||||
$sessions[] = [
|
||||
'id' => 'remember_' . $token['id'],
|
||||
'type' => 'remember',
|
||||
'device' => $this->parseUserAgent($token['user_agent'] ?? ''),
|
||||
'ip_address' => $token['ip_address'] ?? 'Unknown',
|
||||
'created_at' => $token['created_at'],
|
||||
'expires_at' => $token['expires_at'],
|
||||
'is_current' => false,
|
||||
];
|
||||
}
|
||||
|
||||
return $sessions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Парсинг User Agent для получения информации об устройстве
|
||||
*/
|
||||
protected function parseUserAgent(string $userAgent): string
|
||||
{
|
||||
if (empty($userAgent)) {
|
||||
return 'Неизвестное устройство';
|
||||
}
|
||||
|
||||
// Определяем браузер
|
||||
$browser = 'Unknown';
|
||||
if (preg_match('/Firefox\/([0-9.]+)/', $userAgent, $matches)) {
|
||||
$browser = 'Firefox';
|
||||
} elseif (preg_match('/Chrome\/([0-9.]+)/', $userAgent, $matches)) {
|
||||
$browser = 'Chrome';
|
||||
} elseif (preg_match('/Safari\/([0-9.]+)/', $userAgent, $matches)) {
|
||||
$browser = 'Safari';
|
||||
} elseif (preg_match('/MSIE\s+([0-9.]+)/', $userAgent, $matches) || preg_match('/Trident\/([0-9.]+)/', $userAgent, $matches)) {
|
||||
$browser = 'Internet Explorer';
|
||||
} elseif (preg_match('/Edg\/([0-9.]+)/', $userAgent, $matches)) {
|
||||
$browser = 'Edge';
|
||||
}
|
||||
|
||||
// Определяем ОС
|
||||
$os = 'Unknown OS';
|
||||
if (preg_match('/Windows/', $userAgent)) {
|
||||
$os = 'Windows';
|
||||
} elseif (preg_match('/Mac OS X/', $userAgent)) {
|
||||
$os = 'macOS';
|
||||
} elseif (preg_match('/Linux/', $userAgent)) {
|
||||
$os = 'Linux';
|
||||
} elseif (preg_match('/Android/', $userAgent)) {
|
||||
$os = 'Android';
|
||||
} elseif (preg_match('/iPhone|iPad|iPod/', $userAgent)) {
|
||||
$os = 'iOS';
|
||||
}
|
||||
|
||||
return "{$browser} на {$os}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Завершение конкретной сессии
|
||||
*/
|
||||
public function revokeSession()
|
||||
{
|
||||
$userId = $this->getCurrentUserId();
|
||||
$sessionId = $this->request->getPost('session_id');
|
||||
|
||||
if (empty($sessionId)) {
|
||||
return redirect()->to('/profile/security')->with('error', 'Сессия не найдена');
|
||||
}
|
||||
|
||||
$db = \Config\Database::connect();
|
||||
|
||||
// Проверяем, что сессия принадлежит пользователю
|
||||
if (strpos($sessionId, 'remember_') === 0) {
|
||||
// Это remember-токен
|
||||
$tokenId = (int) str_replace('remember_', '', $sessionId);
|
||||
$token = $db->table('remember_tokens')
|
||||
->where('id', $tokenId)
|
||||
->where('user_id', $userId)
|
||||
->get()
|
||||
->getRowArray();
|
||||
|
||||
if ($token) {
|
||||
$db->table('remember_tokens')->where('id', $tokenId)->delete();
|
||||
log_message('info', "User {$userId} revoked remember token {$tokenId}");
|
||||
}
|
||||
}
|
||||
|
||||
return redirect()->to('/profile/security')->with('success', 'Сессия завершена');
|
||||
}
|
||||
|
||||
/**
|
||||
* Завершение всех сессий (кроме текущей)
|
||||
*/
|
||||
public function revokeAllSessions()
|
||||
{
|
||||
$userId = $this->getCurrentUserId();
|
||||
|
||||
// Удаляем все remember-токены
|
||||
$db = \Config\Database::connect();
|
||||
$db->table('remember_tokens')->where('user_id', $userId)->delete();
|
||||
|
||||
// Регенерируем текущую сессию
|
||||
$this->session->regenerate(true);
|
||||
|
||||
log_message('info', "User {$userId} revoked all sessions");
|
||||
|
||||
return redirect()->to('/profile/security')->with(
|
||||
'success',
|
||||
'Все сессии на других устройствах завершены. Вы остались авторизованы на текущем устройстве.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновление имени пользователя
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user