add superadmin dashboard. subscriptions

This commit is contained in:
root
2026-01-13 20:03:16 +03:00
parent 3c24c250e5
commit edb4df7e37
36 changed files with 3329 additions and 100 deletions
+133
View File
@@ -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',
'Все сессии на других устройствах завершены. Вы остались авторизованы на текущем устройстве.'
);
}
/**
* Обновление имени пользователя
*/