fix(rotate): record PPSK rotation password + sync banded-SSID siblings
Three bugs reported from prod after a PPSK rotation: 1. unifi.password_rotation.last_password was only saved after a whole-SSID rotation. PPSK-only setups (the typical guest-WiFi case) ran a successful rotation but the setting stayed empty, so the Settings → Tasks UI never showed the current password and the /api/unifi/wifi/current-password endpoint returned 404 "no rotated password recorded yet". The PPSK loop now writes last_password on every successful PPSK rotation. 2. When an SSID is "banded" (band-steering disabled), UniFi splits it into one wlanconf per band — 2.4GHz and 5GHz each get their own _id and their own embedded PPSK array. Rotating the PPSK on one band left the other band with the old password. New UnifiApiClient::getWlanSiblings($wlanId) finds all wlanconfs that share an SSID name; both rotation and the manual modal edit now call updateEmbeddedPpsk on each sibling and update the matching UnifiPpsk DB rows. 3. The manual WiFi modal edit had the same band-blindness as #2 — editing the GUEST PPSK on the 2.4GHz half left the 5GHz half stale. WifiController::ppskUpdate now walks siblings the same way. v1.8.1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -312,6 +312,40 @@ class UnifiApiClient
|
||||
return $this->put("/rest/wlanconf/{$wlanId}", $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find sibling WLAN configs — same SSID name, different _id. UniFi
|
||||
* splits a "banded" SSID (band-steering disabled) into one wlanconf
|
||||
* per band, each with its own _id and its own embedded PPSK array.
|
||||
* A rotation that updates one band must also update the others, or
|
||||
* the SSID's two halves drift out of sync.
|
||||
*
|
||||
* Returns an array of sibling wlan IDs (excludes $wlanId itself).
|
||||
* Empty array if the target WLAN is unique or can't be found.
|
||||
*/
|
||||
public function getWlanSiblings(string $wlanId): array
|
||||
{
|
||||
try {
|
||||
$all = $this->get('/rest/wlanconf');
|
||||
} catch (\Throwable) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$target = null;
|
||||
foreach ($all as $w) {
|
||||
if (($w['_id'] ?? null) === $wlanId) { $target = $w; break; }
|
||||
}
|
||||
if (! $target || empty($target['name'])) return [];
|
||||
|
||||
$siblings = [];
|
||||
foreach ($all as $w) {
|
||||
if (($w['_id'] ?? null) === $wlanId) continue;
|
||||
if (($w['name'] ?? null) === $target['name']) {
|
||||
$siblings[] = $w['_id'];
|
||||
}
|
||||
}
|
||||
return $siblings;
|
||||
}
|
||||
|
||||
// ── PPSK ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user