117 lines
3.4 KiB
PHP
117 lines
3.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use Hypervel\Http\Request;
|
|
use Hypervel\Support\Facades\Cache;
|
|
use Hypervel\Support\Facades\Response;
|
|
use Hypervel\Support\Facades\Redis;
|
|
use App\Models\User;
|
|
use App\Enums\UserTypes;
|
|
use App\Enums\UserActions;
|
|
use App\Http\Controllers\Helpers\Permissions\UserPermissions;
|
|
use App\Enums\UserActions as UserActionEnum;
|
|
|
|
class RemoteLogoutController
|
|
{
|
|
/**
|
|
* Perform remote logout for a target user.
|
|
*
|
|
* This method finds the Redis key that contains session data for the target user
|
|
* and erases it, effectively logging them out from all devices/sessions.
|
|
*
|
|
* @param string $hashkey The hashkey of the target user to logout
|
|
* @return bool True if logout was successful, false otherwise
|
|
*/
|
|
public static function remoteLogout(string $hashkey): bool
|
|
{
|
|
// Validate that hashkey is provided and is a valid string
|
|
if (!$hashkey || !is_string($hashkey)) {
|
|
return false;
|
|
}
|
|
|
|
// Find the user by hashkey to verify they exist
|
|
$user = User::where('hashkey', $hashkey)->first();
|
|
|
|
if (!$user) {
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
// Set a forced logout flag in Redis with 60s TTL.
|
|
// The SSE stream checks this flag each tick and signals
|
|
// the client to logout when it detects it.
|
|
Redis::setex("forced_logout:{$hashkey}", 60, '1');
|
|
|
|
return true;
|
|
|
|
} catch (\Throwable $th) {
|
|
throw new \Exception('Error during remote logout: ' . $th->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* HTTP endpoint for remote logout.
|
|
*
|
|
* @param Request $request
|
|
* @return ResponseInterface
|
|
*/
|
|
public function logout(Request $request): ResponseInterface
|
|
{
|
|
$hashkey = $request->input('target_user');
|
|
|
|
if (!$hashkey || !is_string($hashkey)) {
|
|
return Response::json([
|
|
'success' => false,
|
|
'message' => 'Invalid or missing target user hashkey.'
|
|
], 400);
|
|
}
|
|
|
|
try {
|
|
$result = self::remoteLogout($hashkey);
|
|
|
|
if (!$result) {
|
|
return Response::json([
|
|
'success' => false,
|
|
'message' => 'Failed to logout user. User may not exist or has no active sessions.'
|
|
], 404);
|
|
}
|
|
|
|
return Response::json([
|
|
'success' => true,
|
|
'message' => 'Remote logout successful.',
|
|
]);
|
|
|
|
} catch (\Throwable $th) {
|
|
return Response::json([
|
|
'success' => false,
|
|
'message' => 'Error performing remote logout: ' . $th->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if a user can be logged out based on permissions.
|
|
*
|
|
* @param string $hashkey The hashkey of the target user
|
|
* @return bool True if logout is allowed, false otherwise
|
|
*/
|
|
public static function canLogout(string $hashkey): bool
|
|
{
|
|
// Validate that hashkey is provided and is a valid string
|
|
if (!$hashkey || !is_string($hashkey)) {
|
|
return false;
|
|
}
|
|
|
|
// Find the user by hashkey to verify they exist
|
|
$user = User::where('hashkey', $hashkey)->first();
|
|
|
|
if (!$user) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
} |