Files

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']);
}
}