Skip to content

Commit 84ca64f

Browse files
Miguel AngelMiguel Angel
andauthored
FOUR-13910 block duplicate session in device restriction only works when the initial browser has the session open (#6121)
* feat: check all active sessions in block session by device * fix: session control middlewares * fix: refactor session expiration --------- Co-authored-by: Miguel Angel <miguelangel@Miguels-MacBook-Pro.local>
1 parent d8eb225 commit 84ca64f

3 files changed

Lines changed: 40 additions & 34 deletions

File tree

‎ProcessMaker/Http/Middleware/SessionControlBlock.php‎

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -97,21 +97,28 @@ private function blockSessionByDevice(User $user, Request $request): bool
9797
$requestDevice = $this->formatDeviceInfo($agentDevice, $agent->deviceType(), $agent->platform());
9898
// Get the user's current IP address
9999
$ip = $request->getClientIp() ?? $request->ip();
100-
// Get the user's most recent session
101-
$session = $user->sessions()
102-
->where('is_active', true)
100+
// Get the active user sessions
101+
$sessions = $user->sessions()
102+
->where([
103+
['is_active', true],
104+
['expired_date', null],
105+
])
103106
->orderBy('created_at', 'desc')
104-
->first();
107+
->get();
105108

106-
if ($session) {
109+
$openSessions = $sessions->reduce(function ($carry, $session) use ($requestDevice, $ip) {
107110
$sessionDevice = $this->formatDeviceInfo(
108111
$session->device_name, $session->device_type, $session->device_platform
109112
);
110113

111-
return $requestDevice !== $sessionDevice || $session->ip_address !== $ip;
112-
}
114+
if ($requestDevice !== $sessionDevice || $session->ip_address !== $ip) {
115+
return $carry + 1;
116+
} else {
117+
return $carry - 1;
118+
}
119+
}, 0);
113120

114-
return false;
121+
return $openSessions > 0;
115122
}
116123

117124
private function formatDeviceInfo(string $deviceName, string $deviceType, string $devicePlatform): string

‎ProcessMaker/Http/Middleware/SessionControlKill.php‎

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,17 @@ public function handle(Request $request, Closure $next): Response
3434

3535
$session = $this->getActiveSession($user, $userSession);
3636

37-
// Checks if the session has expired based on the IP address
38-
if ($session && $configIP === '2' && $this->isSessionExpiredByIP($session, $request)) {
39-
return $this->killSessionAndRedirect($session);
40-
}
41-
// Checks if the session has expired based on the device
42-
if ($session && $configDevice === '2' && $this->isSessionExpiredByDevice($session)) {
43-
return $this->killSessionAndRedirect($session);
37+
if ($session) {
38+
// Checks if the session has expired based on the IP address
39+
$isSessionExpiredByIP = $configIP === '2' && $this->isSessionExpiredByIP($session, $request);
40+
// Checks if the session has expired based on the device
41+
$isSessionExpiredByDevice = $configDevice === '2' && $this->isSessionExpiredByDevice($session);
42+
// Checks if the session has expired except the one within the active device
43+
$isAnyRestrictionEnabled = $configIP === '1' || $configDevice === '1';
44+
45+
if ($isSessionExpiredByIP || $isSessionExpiredByDevice || $isAnyRestrictionEnabled) {
46+
return $this->killSessionAndRedirect($session);
47+
}
4448
}
4549
}
4650

‎ProcessMaker/Models/UserSession.php‎

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,15 @@ public static function expiresDuplicatedSessionByIP()
3838
{
3939
$usersActiveIP = [];
4040
self::where('is_active', true)
41-
->where('expired_date', null)
42-
->orderBy('id', 'desc')
41+
->whereNull('expired_date')
42+
->orderBy('user_id', 'asc')
43+
->orderBy('created_at', 'desc')
4344
->chunk(100, function ($sessions) use (&$usersActiveIP) {
4445
foreach ($sessions as $session) {
45-
$key = $session->user_id . '.' . $session->ip_address;
46-
if (!isset($usersActiveIP[$session->user_id])) {
47-
$usersActiveIP[$session->user_id] = $key;
48-
}
49-
// expire all sessions except the ones within the active IP
50-
if ($usersActiveIP[$session->user_id] !== $key) {
46+
if (!array_key_exists($session->user_id, $usersActiveIP)) {
47+
$usersActiveIP[$session->user_id] = $session->user_id;
48+
} else {
49+
// expire all sessions except the ones within the active IP
5150
$session->update(['expired_date' => now()]);
5251
}
5352
}
@@ -61,19 +60,15 @@ public static function expiresDuplicatedSessionByDevice()
6160
{
6261
$usersActiveDevice = [];
6362
self::where('is_active', true)
64-
->where('expired_date', null)
65-
->orderBy('id', 'desc')
63+
->whereNull('expired_date')
64+
->orderBy('user_id', 'asc')
65+
->orderBy('created_at', 'desc')
6666
->chunk(100, function ($sessions) use (&$usersActiveDevice) {
6767
foreach ($sessions as $session) {
68-
$key = $session->user_id . '.' .
69-
$session->device_name . '.' .
70-
$session->device_type . '.' .
71-
$session->device_platform;
72-
if (!isset($usersActiveDevice[$session->user_id])) {
73-
$usersActiveDevice[$session->user_id] = $key;
74-
}
75-
// expire all sessions except the ones within the active device
76-
if ($usersActiveDevice[$session->user_id] !== $key) {
68+
if (!array_key_exists($session->user_id, $usersActiveDevice)) {
69+
$usersActiveDevice[$session->user_id] = $session->user_id;
70+
} else {
71+
// expire all sessions except the ones within the active device
7772
$session->update(['expired_date' => now()]);
7873
}
7974
}

0 commit comments

Comments
 (0)