Level 11
Resolved!!!
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
So i have a livewire component for displaying and deleting sessions.
Component
<?php
namespace App\Livewire\Dashboard\UserDashboard\Security;
use Livewire\Component;
use App\Models\Profile\UserSessions as Sessions;
use Illuminate\Support\Facades\Session;
use UAParser\Parser;
use Illuminate\Support\Facades\Auth;
class LoggedInDevices extends Component
{
public $sessions = [];
public $sessionToTerminate = null;
public function mount()
{
$this->loggedInDevices();
}
public function loggedInDevices()
{
$user = Auth::user();
if (!$user) {
logger('No authenticated user found');
return;
}
$get_sessions = Sessions::where('user_id', $user->id)->get();
logger('Retrieved sessions', [
'user_id' => $user->id,
'session_count' => $get_sessions->count(),
'sessions' => $get_sessions->pluck('id')->toArray()
]);
$devices = [];
$parser = Parser::create();
foreach ($get_sessions as $session) {
$result = $parser->parse($session->user_agent);
$device_name = $result->ua->family
? $result->ua->family . ' ' . $result->ua->toVersion()
: 'Unknown Device';
$devices[] = [
'device_name' => $device_name,
'device_icon' => $this->getDeviceIcon($result->ua->family ?: 'default'),
'last_activity' => $session->last_activity,
'session_id' => $session->id,
'session_ip' => $session->ip_address,
];
}
$this->sessions = $devices;
}
protected function getDeviceIcon($deviceName)
{
switch (strtolower($deviceName)) {
case 'chrome':
return 'fa-brands fa-chrome';
case 'firefox':
return 'fa-brands fa-firefox';
case 'safari':
return 'fa-brands fa-safari';
case 'opera':
return 'fa-brands fa-opera';
case 'edge':
return 'fa-brands fa-edge';
case 'android':
return 'fa-brands fa-android';
case 'ios':
return 'fa-brands fa-apple';
case 'windows':
return 'fa-brands fa-windows';
case 'mac':
case 'macos':
return 'fa-brands fa-apple';
case 'linux':
return 'fa-brands fa-linux';
default:
return 'fa-solid fa-desktop';
}
}
public function terminateSession($sessionId = null)
{
try {
$user = Auth::user();
if (!$user) {
throw new \Exception('User not authenticated');
}
$sessionId = Session::getId();
if (!$sessionId) {
throw new \Exception('No session ID provided');
}
logger('Termination attempt', [
'session_id' => $sessionId,
'user_id' => $user->id,
'current_session_id' => Session::getId()
]);
$session = Sessions::where('id', $sessionId)
->where('user_id', $user->id)
->first();
if (!$session) {
logger('Session not found', [
'session_id' => $sessionId,
'user_id' => $user->id,
'available_sessions' => Sessions::where('user_id', $user->id)->pluck('id')->toArray()
]);
throw new \Exception('Session not found in database');
}
logger('Session found', [
'session_data' => $session->toArray()
]);
$isCurrentSession = Session::getId() === $sessionId;
$deleted = $session->delete();
if ($deleted) {
if ($isCurrentSession) {
logger('Terminating current session');
Auth::logout();
Session::flush();
Session::regenerate(true); // Regenerate session ID
$this->dispatch('session-terminated-current', ['message' => 'Current session terminated']);
return redirect()->route('login');
}
logger('Session successfully deleted', ['session_id' => $sessionId]);
$this->sessions = [];
$this->loggedInDevices();
$this->dispatch('session-terminated', ['message' => 'Session terminated successfully!']);
flash()
->option('position', 'bottom-center')
->option('timeout', 3000)
->success('Session terminated successfully!');
} else {
flash()
->option('position', 'bottom-center')
->option('timeout', 3000)
->error('Failed to terminate session');
logger('Session deletion failed', [
'session_id' => $sessionId,
'user_id' => $user->id
]);
}
} catch (\Exception $e) {
logger('Session termination failed', [
'error' => $e->getMessage(),
'session_id' => $sessionId ?? 'none',
'user_id' => $user->id ?? 'none',
'trace' => $e->getTraceAsString()
]);
flash()
->option('position', 'bottom-center')
->option('timeout', 3000)
->error('Failed to terminate session: ' . $e->getMessage());
}
$this->sessionToTerminate = null;
}
public function render()
{
return view('livewire.dashboard.user-dashboard.security.logged-in-devices')
->extends('layouts.dashboard.user')
->section('content');
}
}
view
<div>
<div class="pc-container">
<div class="pc-content">
<!-- [ breadcrumb ] start -->
<div class="page-header">
<div class="page-block">
<div class="row align-items-center">
<div class="col-md-12">
<ul class="breadcrumb">
<li class="breadcrumb-item">
<a href="javascript: void(0)">Security</a>
</li>
<li class="breadcrumb-item" aria-current="page">
<a href="javascript: void(0)">Logged In Devices</a>
</li>
</ul>
</div>
<div class="col-md-12 mt-3">
<div class="page-header-title">
<h2 class="mb-0">Logged In Devices</h2>
</div>
</div>
</div>
</div>
</div>
<!-- [ breadcrumb ] end -->
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4">
@forelse($sessions as $session)
<div class="col">
<div class="card h-100" style="border: none; border-radius: 15px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); transition: transform 0.3s ease-in-out;">
<div class="card-body d-flex flex-column align-items-center">
<i class="fas {{ $session['device_icon'] }} mb-3" style="font-size: 2rem; color: #6c757d;"></i>
<h5 class="card-title" style="font-weight: bold; color: #495057;">
{{ $session['device_name'] }}
</h5>
<p class="card-text text-center" style="color: #6c757d; font-size: 0.9rem;">
Last active: {{ \Carbon\Carbon::createFromTimestamp($session['last_activity'])->diffForHumans() }}<br>
</p>
<p class="card-text text-center" style="color: #6c757d; font-size: 0.9rem;">
@php
$location = \Location::get($session['session_ip']);
@endphp
IP Address: {{ $session['session_ip'] }}
@if ($location)
({{ $location->countryName }})
@else
(Location not available)
@endif
<br>
</p>
<button
type="button"
class="btn btn-danger"
data-bs-toggle="modal"
data-bs-target="#terminateModal-{{ $session['session_id'] }}"
wire:click="$set('sessionToTerminate', '{{ $session['session_id'] }}')"
>
Terminate Session
</button>
</div>
</div>
</div>
<!-- Unique Modal for each session -->
<div class="modal fade" id="terminateModal-{{ $session['session_id'] }}" tabindex="-1" aria-labelledby="terminateModalLabel-{{ $session['session_id'] }}" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="terminateModalLabel-{{ $session['session_id'] }}">Confirm Termination</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Are you sure you want to terminate this session?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button
type="button"
class="btn btn-danger"
wire:click="terminateSession('{{ $session['session_id'] }}')"
data-bs-dismiss="modal"
wire:loading.attr="disabled"
>
<span wire:loading wire:target="terminateSession" class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
Terminate
</button>
</div>
</div>
</div>
</div>
@empty
<div class="col">
<div class="card h-100 text-center" style="border: none; border-radius: 15px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);">
<div class="card-body">
<p class="text-muted">No active sessions found.</p>
</div>
</div>
</div>
@endforelse
</div>
</div>
</div>
<script>
document.addEventListener('livewire:init', function () {
window.addEventListener('session-terminated', event => {
console.log('Session terminated:', event.detail.message);
});
});
</script>
</div>
So i want to basically delete for individual session. I had a way of doing this in laravel 9 or so but some changes were made which returns error "Session id not found"
Resolved!!!
Please or to participate in this conversation.