84 lines
3.0 KiB
PHP
84 lines
3.0 KiB
PHP
<?php
|
|
namespace App\Traits;
|
|
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
trait SwitchGuardTrait
|
|
{
|
|
/**
|
|
* Switches the authentication guard to the specified guard and logs in the given profile.
|
|
*
|
|
* This method logs out the user from all other guards except the specified new guard,
|
|
* then logs in the provided profile using the new guard and updates the session to
|
|
* reflect the active guard.
|
|
*
|
|
* @param string $newGuard The name of the guard to switch to (e.g., 'web', 'admin', 'bank', 'organization').
|
|
* @param \Illuminate\Contracts\Auth\Authenticatable $profile The user profile to log in with the new guard.
|
|
* @return void
|
|
*/
|
|
function switchGuard($newGuard, $profile) {
|
|
foreach (['admin', 'bank', 'organization'] as $guard) {
|
|
if ($guard !== $newGuard) {
|
|
Auth::guard($guard)->logout();
|
|
}
|
|
}
|
|
Auth::guard($newGuard)->login($profile);
|
|
session(['active_guard' => $newGuard]);
|
|
}
|
|
|
|
|
|
/**
|
|
* Logs out users from all non-web authentication guards ('admin', 'bank', 'organization')
|
|
* and sets the session 'active_guard' to 'web'.
|
|
*
|
|
* This method is useful for ensuring that only the 'web' guard remains active,
|
|
* preventing conflicts when switching between different user roles.
|
|
*
|
|
* @return void
|
|
*/
|
|
/**
|
|
* Validates that a URL is local to prevent open redirect attacks.
|
|
* Accepts relative paths (/foo) and absolute URLs whose host matches the request host.
|
|
* Returns null if the URL is external or unsafe.
|
|
*/
|
|
protected function validateLocalUrl(?string $url, \Illuminate\Http\Request $request): ?string
|
|
{
|
|
if (!$url) {
|
|
return null;
|
|
}
|
|
// Relative path (but not protocol-relative //)
|
|
if (str_starts_with($url, '/') && !str_starts_with($url, '//')) {
|
|
return $url;
|
|
}
|
|
// Absolute URL — allow only if same host as the current request
|
|
$parsed = parse_url($url);
|
|
if (isset($parsed['host']) && $parsed['host'] === $request->getHost()) {
|
|
return $url;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public function logoutNonWebGuards()
|
|
{
|
|
$presenceService = app(\App\Services\PresenceService::class);
|
|
|
|
foreach (['admin', 'bank', 'organization'] as $guard) {
|
|
// Set the user offline before logging out
|
|
if (Auth::guard($guard)->check()) {
|
|
$user = Auth::guard($guard)->user();
|
|
$presenceService->setUserOffline($user, $guard);
|
|
|
|
// Explicitly clear all caches for this user/guard combination
|
|
\Cache::forget("presence_{$guard}_{$user->id}");
|
|
\Cache::forget("presence_last_update_{$guard}_{$user->id}");
|
|
}
|
|
|
|
// Clear the guard's online users cache
|
|
\Cache::forget("online_users_{$guard}_" . \App\Services\PresenceService::ONLINE_THRESHOLD_MINUTES);
|
|
|
|
Auth::guard($guard)->logout();
|
|
}
|
|
|
|
session(['active_guard' => 'web']);
|
|
}
|
|
} |