diff --git a/ProcessMaker/Http/Middleware/SessionControlBlock.php b/ProcessMaker/Http/Middleware/SessionControlBlock.php index a61ae52dbe..789083f0b8 100644 --- a/ProcessMaker/Http/Middleware/SessionControlBlock.php +++ b/ProcessMaker/Http/Middleware/SessionControlBlock.php @@ -97,21 +97,28 @@ private function blockSessionByDevice(User $user, Request $request): bool $requestDevice = $this->formatDeviceInfo($agentDevice, $agent->deviceType(), $agent->platform()); // Get the user's current IP address $ip = $request->getClientIp() ?? $request->ip(); - // Get the user's most recent session - $session = $user->sessions() - ->where('is_active', true) + // Get the active user sessions + $sessions = $user->sessions() + ->where([ + ['is_active', true], + ['expired_date', null], + ]) ->orderBy('created_at', 'desc') - ->first(); + ->get(); - if ($session) { + $openSessions = $sessions->reduce(function ($carry, $session) use ($requestDevice, $ip) { $sessionDevice = $this->formatDeviceInfo( $session->device_name, $session->device_type, $session->device_platform ); - return $requestDevice !== $sessionDevice || $session->ip_address !== $ip; - } + if ($requestDevice !== $sessionDevice || $session->ip_address !== $ip) { + return $carry + 1; + } else { + return $carry - 1; + } + }, 0); - return false; + return $openSessions > 0; } private function formatDeviceInfo(string $deviceName, string $deviceType, string $devicePlatform): string diff --git a/ProcessMaker/Http/Middleware/SessionControlKill.php b/ProcessMaker/Http/Middleware/SessionControlKill.php index bcc18be214..24f4f76e6d 100644 --- a/ProcessMaker/Http/Middleware/SessionControlKill.php +++ b/ProcessMaker/Http/Middleware/SessionControlKill.php @@ -34,13 +34,17 @@ public function handle(Request $request, Closure $next): Response $session = $this->getActiveSession($user, $userSession); - // Checks if the session has expired based on the IP address - if ($session && $configIP === '2' && $this->isSessionExpiredByIP($session, $request)) { - return $this->killSessionAndRedirect($session); - } - // Checks if the session has expired based on the device - if ($session && $configDevice === '2' && $this->isSessionExpiredByDevice($session)) { - return $this->killSessionAndRedirect($session); + if ($session) { + // Checks if the session has expired based on the IP address + $isSessionExpiredByIP = $configIP === '2' && $this->isSessionExpiredByIP($session, $request); + // Checks if the session has expired based on the device + $isSessionExpiredByDevice = $configDevice === '2' && $this->isSessionExpiredByDevice($session); + // Checks if the session has expired except the one within the active device + $isAnyRestrictionEnabled = $configIP === '1' || $configDevice === '1'; + + if ($isSessionExpiredByIP || $isSessionExpiredByDevice || $isAnyRestrictionEnabled) { + return $this->killSessionAndRedirect($session); + } } } diff --git a/ProcessMaker/Models/UserSession.php b/ProcessMaker/Models/UserSession.php index e9daa7617d..dd1dc5c8d7 100644 --- a/ProcessMaker/Models/UserSession.php +++ b/ProcessMaker/Models/UserSession.php @@ -38,16 +38,15 @@ public static function expiresDuplicatedSessionByIP() { $usersActiveIP = []; self::where('is_active', true) - ->where('expired_date', null) - ->orderBy('id', 'desc') + ->whereNull('expired_date') + ->orderBy('user_id', 'asc') + ->orderBy('created_at', 'desc') ->chunk(100, function ($sessions) use (&$usersActiveIP) { foreach ($sessions as $session) { - $key = $session->user_id . '.' . $session->ip_address; - if (!isset($usersActiveIP[$session->user_id])) { - $usersActiveIP[$session->user_id] = $key; - } - // expire all sessions except the ones within the active IP - if ($usersActiveIP[$session->user_id] !== $key) { + if (!array_key_exists($session->user_id, $usersActiveIP)) { + $usersActiveIP[$session->user_id] = $session->user_id; + } else { + // expire all sessions except the ones within the active IP $session->update(['expired_date' => now()]); } } @@ -61,19 +60,15 @@ public static function expiresDuplicatedSessionByDevice() { $usersActiveDevice = []; self::where('is_active', true) - ->where('expired_date', null) - ->orderBy('id', 'desc') + ->whereNull('expired_date') + ->orderBy('user_id', 'asc') + ->orderBy('created_at', 'desc') ->chunk(100, function ($sessions) use (&$usersActiveDevice) { foreach ($sessions as $session) { - $key = $session->user_id . '.' . - $session->device_name . '.' . - $session->device_type . '.' . - $session->device_platform; - if (!isset($usersActiveDevice[$session->user_id])) { - $usersActiveDevice[$session->user_id] = $key; - } - // expire all sessions except the ones within the active device - if ($usersActiveDevice[$session->user_id] !== $key) { + if (!array_key_exists($session->user_id, $usersActiveDevice)) { + $usersActiveDevice[$session->user_id] = $session->user_id; + } else { + // expire all sessions except the ones within the active device $session->update(['expired_date' => now()]); } }