2 Commits

Author SHA1 Message Date
429cd44ac5 fix: register unifi pages with shell NavVisibilityRegistry; v1.12.1
The Access tab persists user/group grants in unifi_page_grants and the
existing RouteMatched listener honors them on the request path, but
NavItem::visibleTo() only consulted the page's required_permission —
so a granted user never saw the menu entry to reach the page. Register
the unifi.* prefix with the shell's NavVisibilityRegistry so the
sidebar lists exactly the pages the grant table allows.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 12:12:58 -04:00
274f210337 release: 1.12.0 — rolls up 1.11.1 (reboot suppression hardening)
Bundled stable cut for prod. Contents since 1.11.0:

* fix(reboot): suppress webhook alerts during a fleet reboot
  regardless of cache driver. RebootAllAps now stamps a Setting
  (unifi.reboot_suppression_until) for 20 minutes at the start of a
  fleet reboot, and WebhookCheckService consults that Setting in
  checkDeviceTransition + checkReboot in addition to the existing
  per-MAC cache keys. Database-backed Setting always crosses
  container/process/cache-driver boundaries so the suppression can
  no longer be defeated by config differences.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:09:08 -04:00
2 changed files with 26 additions and 1 deletions

View File

@@ -1,7 +1,7 @@
{ {
"name": "dashboard/unifi", "name": "dashboard/unifi",
"description": "UniFi network management, WiFi stats, and captive portal authentication for the Dashboard platform", "description": "UniFi network management, WiFi stats, and captive portal authentication for the Dashboard platform",
"version": "1.11.1", "version": "1.12.1",
"type": "library", "type": "library",
"license": "MIT", "license": "MIT",
"autoload": { "autoload": {

View File

@@ -25,6 +25,31 @@ class UnifiServiceProvider extends ServiceProvider
$this->loadRoutesFrom(__DIR__ . '/routes/unifi.php'); $this->loadRoutesFrom(__DIR__ . '/routes/unifi.php');
$this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); $this->loadMigrationsFrom(__DIR__ . '/../database/migrations');
// Tell the shell's NavVisibilityRegistry which unifi nav items
// the user can see in the sidebar. Without this the sidebar
// would only follow legacy required_permission, hiding pages
// the user has been explicitly granted via the Access tab.
try {
app(\App\Support\NavVisibilityRegistry::class)->register(
'unifi.',
function (\App\Models\User $user) {
if (! \Illuminate\Support\Facades\Schema::hasTable('unifi_page_grants')) {
return collect();
}
$groupIds = $user->groups()->pluck('groups.id');
return UnifiPageGrant::query()
->where(function ($q) use ($user, $groupIds) {
$q->where(fn ($u) => $u->where('grantee_type', 'user')->where('grantee_id', $user->id))
->orWhere(fn ($g) => $g->where('grantee_type', 'group')->whereIn('grantee_id', $groupIds));
})
->pluck('nav_item_id');
}
);
} catch (\Throwable) {
// Shell may not have the registry yet (older shell version).
// Sidebar will fall back to legacy permission filter.
}
// Per-page access enforcement for unifi routes. If a unifi page has // Per-page access enforcement for unifi routes. If a unifi page has
// any UnifiPageGrant rows, only super-admins and granted users/ // any UnifiPageGrant rows, only super-admins and granted users/
// groups can hit it; otherwise (no grants) it's open per the existing // groups can hit it; otherwise (no grants) it's open per the existing