From 52a48ef6793d51b479df1aef2c3b6b4ef6a23ce6 Mon Sep 17 00:00:00 2001 From: Miguel Angel Date: Tue, 30 Jan 2024 16:01:15 -0400 Subject: [PATCH 1/3] feat: check all active sessions in block session by device --- .../Http/Middleware/SessionControlBlock.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/ProcessMaker/Http/Middleware/SessionControlBlock.php b/ProcessMaker/Http/Middleware/SessionControlBlock.php index a61ae52dbe..36d6b224f7 100644 --- a/ProcessMaker/Http/Middleware/SessionControlBlock.php +++ b/ProcessMaker/Http/Middleware/SessionControlBlock.php @@ -97,21 +97,25 @@ 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() + // Get the active user sessions + $sessions = $user->sessions() ->where('is_active', true) ->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 From 4efb34bc3f4d84c9316d5c40eb6810c7c6032e02 Mon Sep 17 00:00:00 2001 From: Miguel Angel Date: Wed, 31 Jan 2024 09:39:09 -0400 Subject: [PATCH 2/3] fix: session control middlewares --- .../Http/Middleware/SessionControlBlock.php | 5 ++++- .../Http/Middleware/SessionControlKill.php | 18 +++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ProcessMaker/Http/Middleware/SessionControlBlock.php b/ProcessMaker/Http/Middleware/SessionControlBlock.php index 36d6b224f7..789083f0b8 100644 --- a/ProcessMaker/Http/Middleware/SessionControlBlock.php +++ b/ProcessMaker/Http/Middleware/SessionControlBlock.php @@ -99,7 +99,10 @@ private function blockSessionByDevice(User $user, Request $request): bool $ip = $request->getClientIp() ?? $request->ip(); // Get the active user sessions $sessions = $user->sessions() - ->where('is_active', true) + ->where([ + ['is_active', true], + ['expired_date', null], + ]) ->orderBy('created_at', 'desc') ->get(); 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); + } } } From 584be7543d6288c0ff1695ec53b272e304650c0e Mon Sep 17 00:00:00 2001 From: Miguel Angel Date: Wed, 31 Jan 2024 12:27:17 -0400 Subject: [PATCH 3/3] fix: refactor session expiration --- ProcessMaker/Models/UserSession.php | 33 ++++++++++++----------------- 1 file changed, 14 insertions(+), 19 deletions(-) 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()]); } }