Network presence no longer frees a device slot
This commit is contained in:
@@ -164,28 +164,30 @@ class PortalController extends Controller
|
||||
return Inertia::render('Unifi/PortalDenied', ['reason' => 'No WiFi access configured for your account.']);
|
||||
}
|
||||
|
||||
// Check device limit
|
||||
$activeSessions = PortalSession::where('user_id', $user->id)
|
||||
->where('is_active', true)
|
||||
->get();
|
||||
/*
|
||||
* Presence is NOT the question — a live authorization is.
|
||||
*
|
||||
* This used to walk the user's sessions and mark any device UniFi did not
|
||||
* currently see as stale, freeing its slot. But UniFi holds an
|
||||
* authorization for its whole window regardless of whether the device is
|
||||
* in the building, so a phone that went home had its slot freed while
|
||||
* still being authorized: the owner then authorized a second device and
|
||||
* one of the two was an orphan nothing tracked. The longer
|
||||
* session_minutes is — and it is now meant to be a term — the more of
|
||||
* those accumulate.
|
||||
*
|
||||
* Slots are now freed by eviction, by expiry, or by ReconcilePortal.
|
||||
*/
|
||||
$live = PortalSession::live()->where('user_id', $user->id)->get();
|
||||
|
||||
foreach ($activeSessions as $session) {
|
||||
if ($session->mac_address === $clientMac) {
|
||||
// Same device reconnecting — refresh
|
||||
$session->update(['is_active' => false]);
|
||||
continue;
|
||||
}
|
||||
// Check if other device is still actually connected
|
||||
if (! $unifi->isClientConnected($session->mac_address)) {
|
||||
$session->update(['is_active' => false]); // stale session
|
||||
}
|
||||
}
|
||||
// The same device coming back is a renewal, not a new device: it keeps
|
||||
// its slot and its row, and simply gets a fresh window.
|
||||
$existing = $live->firstWhere('mac_address', $clientMac);
|
||||
|
||||
$activeCount = PortalSession::where('user_id', $user->id)->where('is_active', true)->count();
|
||||
if ($activeCount >= $mapping->max_devices) {
|
||||
if (! $existing && $live->count() >= $mapping->max_devices) {
|
||||
return Inertia::render('Unifi/PortalDenied', [
|
||||
'reason' => "You already have {$activeCount} device(s) connected (limit: {$mapping->max_devices}).",
|
||||
'sessions' => $activeSessions->map(fn ($s) => [
|
||||
'reason' => "You already have {$live->count()} device(s) connected (limit: {$mapping->max_devices}).",
|
||||
'sessions' => $live->map(fn ($s) => [
|
||||
'id' => $s->id,
|
||||
'mac' => $s->mac_address,
|
||||
'hostname' => $s->device_hostname,
|
||||
@@ -200,20 +202,20 @@ class PortalController extends Controller
|
||||
$minutes = $mapping->session_minutes;
|
||||
$unifi->authorizeGuest($clientMac, $minutes);
|
||||
|
||||
// Record the session
|
||||
PortalSession::create([
|
||||
'user_id' => $user->id,
|
||||
'mac_address' => $clientMac,
|
||||
'device_hostname' => $request->input('hostname'),
|
||||
'device_os' => $request->input('os'),
|
||||
'device_type' => $request->input('dev_cat'),
|
||||
'ssid' => $ssid,
|
||||
'vlan_id' => $mapping->vlan_id,
|
||||
'ap_mac' => $apMac,
|
||||
'is_active' => true,
|
||||
'authorized_at' => now(),
|
||||
'expires_at' => now()->addMinutes($minutes),
|
||||
]);
|
||||
PortalSession::updateOrCreate(
|
||||
['user_id' => $user->id, 'mac_address' => $clientMac],
|
||||
[
|
||||
'device_hostname' => $request->input('hostname'),
|
||||
'device_os' => $request->input('os'),
|
||||
'device_type' => $request->input('dev_cat'),
|
||||
'ssid' => $ssid,
|
||||
'vlan_id' => $mapping->vlan_id,
|
||||
'ap_mac' => $apMac,
|
||||
'is_active' => true,
|
||||
'authorized_at' => now(),
|
||||
'expires_at' => now()->addMinutes($minutes),
|
||||
]
|
||||
);
|
||||
|
||||
// Redirect to the original URL the user was trying to reach.
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user