chore: remove AP Groups surfaces (legacy API auth incompatible)

UniFi's /rest/apgroup endpoints (and per-SSID ap_group_ids writes via
/rest/wlanconf) require session-cookie auth — they don't accept the
X-API-Key header. The Integration API doesn't expose AP groups at all.
So with the current deployment running on API-key auth, every AP-group
operation returned 400 api.err.InvalidObject. Removing the dead code
rather than carrying a feature that can't function.

* Deleted ApGroupController, ApGroups.vue, the /ap-groups/* routes,
  and getApGroups/createApGroup/updateApGroup/deleteApGroup from
  UnifiApiClient.
* Removed the per-SSID AP-group assignment from Wifi.vue + the
  updateApGroups action + /wifi/{wlanId}/ap-groups route + the
  ap_group_ids field from the mapWlan output.
* Removed the AP Groups nav entry from composer.json.

If a future deploy adds local-admin username+password auth, AP groups
can be reintroduced — the UnifiApiClient::buildRequest() session-cookie
path is intact.

v1.3.1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-23 16:35:32 -04:00
parent fc4f5370ae
commit a4397c5178
5 changed files with 4 additions and 163 deletions

View File

@@ -1,95 +0,0 @@
<?php
namespace Dashboard\Unifi\Http\Controllers;
use Dashboard\Unifi\Services\UnifiApiClient;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Cache;
use Inertia\Inertia;
class ApGroupController extends Controller
{
public function index(UnifiApiClient $unifi)
{
// Always pull fresh from the controller on this page so the
// operator never edits against a stale snapshot. getApGroups()
// and getWlans() aren't cached, but getDevices() (which feeds
// the AP picker) is — bust it explicitly.
Cache::forget('unifi:devices');
try {
$groups = collect($unifi->getApGroups())->map(fn ($g) => [
'id' => $g['_id'],
'name' => $g['name'] ?? 'Unnamed',
'device_macs' => $g['device_macs'] ?? [],
'is_default' => $g['attr_no_delete'] ?? false,
])->values();
$devices = collect($unifi->getAccessPoints())->map(fn ($d) => [
'mac' => strtolower($d['mac']),
'name' => $d['name'] ?? $d['model'] ?? $d['mac'],
'model' => $d['model'] ?? '',
'state' => $d['state'] ?? 0,
])->values();
return Inertia::render('Unifi/ApGroups', [
'groups' => $groups,
'devices' => $devices,
]);
} catch (\Throwable $e) {
return Inertia::render('Unifi/ApGroups', [
'groups' => [], 'devices' => [], 'error' => $e->getMessage(),
]);
}
}
public function store(Request $request, UnifiApiClient $unifi)
{
$data = $request->validate([
'name' => 'required|string|max:100',
'device_macs' => 'present|array',
'device_macs.*' => 'string',
]);
try {
$result = $unifi->createApGroup([
'name' => $data['name'],
'device_macs' => array_values(array_map('strtolower', $data['device_macs'])),
]);
return back()->with('success', 'AP group created.');
} catch (\Throwable $e) {
return back()->withErrors(['error' => $e->getMessage()]);
}
}
public function update(Request $request, string $groupId, UnifiApiClient $unifi)
{
$data = $request->validate([
'name' => 'sometimes|string|max:100',
'device_macs' => 'sometimes|array',
'device_macs.*' => 'string',
]);
if (isset($data['device_macs'])) {
$data['device_macs'] = array_values(array_map('strtolower', $data['device_macs']));
}
try {
$unifi->updateApGroup($groupId, $data);
return back()->with('success', 'AP group updated.');
} catch (\Throwable $e) {
return back()->withErrors(['error' => $e->getMessage()]);
}
}
public function destroy(string $groupId, UnifiApiClient $unifi)
{
try {
$unifi->deleteApGroup($groupId);
return back()->with('success', 'AP group deleted.');
} catch (\Throwable $e) {
return back()->withErrors(['error' => $e->getMessage()]);
}
}
}

View File

@@ -13,25 +13,9 @@ class WifiController extends Controller
{
public function index(UnifiApiClient $unifi)
{
// Always pull fresh device data on this page so AP-group / SSID
// edits never go out against a stale snapshot. getWlans() and
// getApGroups() aren't cached, but getDevices() is.
\Illuminate\Support\Facades\Cache::forget('unifi:devices');
try {
$wlans = collect($unifi->getWlans())->map(fn ($w) => $this->mapWlan($w))->values();
try {
$apGroups = collect($unifi->getApGroups())->map(fn ($g) => [
'id' => $g['_id'],
'name' => $g['attr_no_delete'] ?? false ? 'Default' : ($g['name'] ?? 'Unnamed'),
'device_macs' => $g['device_macs'] ?? [],
'is_default' => $g['attr_no_delete'] ?? false,
])->values();
} catch (\Throwable $e) {
$apGroups = collect(); // AP groups not supported by this controller
}
$raw = Setting::get('unifi.ssid_groups', '{}');
$groups = json_decode($raw, true);
if (! is_array($groups) || array_is_list($groups)) $groups = [];
@@ -42,13 +26,12 @@ class WifiController extends Controller
return Inertia::render('Unifi/Wifi', [
'wlans' => $wlans,
'groups' => $groups,
'apGroups' => $apGroups,
'rotateWlanIds' => $rotateWlanIds,
'ppskSchedulingEnabled' => (bool) Setting::get('unifi.ppsk_scheduling.enabled', false),
]);
} catch (\Throwable $e) {
return Inertia::render('Unifi/Wifi', [
'wlans' => [], 'groups' => [], 'apGroups' => [], 'rotateWlanIds' => [], 'error' => $e->getMessage(),
'wlans' => [], 'groups' => [], 'rotateWlanIds' => [], 'error' => $e->getMessage(),
]);
}
}
@@ -103,21 +86,6 @@ class WifiController extends Controller
}
}
/**
* Update AP group assignments for a single WLAN (not synced to group siblings).
*/
public function updateApGroups(Request $request, string $wlanId, UnifiApiClient $unifi)
{
$request->validate(['ap_group_ids' => 'required|array']);
try {
$unifi->updateWlan($wlanId, ['ap_group_ids' => $request->ap_group_ids]);
return back()->with('success', 'AP groups updated.');
} catch (\Throwable $e) {
return back()->withErrors(['error' => $e->getMessage()]);
}
}
public function toggle(Request $request, string $wlanId, UnifiApiClient $unifi)
{
$request->validate(['enabled' => 'required|boolean']);
@@ -419,7 +387,6 @@ class WifiController extends Controller
'hide_ssid' => $w['hide_ssid'] ?? false,
'passphrase' => $w['x_passphrase'] ?? '',
'band' => $this->detectBand($w),
'ap_group_ids' => $w['ap_group_ids'] ?? [],
'mac_filter_enabled' => $w['mac_filter_enabled'] ?? false,
'mac_filter_policy' => $w['mac_filter_policy'] ?? 'deny',
'ppsk_enabled' => ($w['wpa3_ppsk'] ?? false)