Fix sidebar navigation not respecting user permissions

Sidebar nav items (Archives, Queue, Stats, Profiles, Maintenance,
  Projects, Inventory, Files) were visible to all users regardless of
  role permissions — only Settings was gated. Now each item is hidden
  when the user lacks the corresponding read permission. Printers
  remains always visible as the home page.

  Also adds missing inventory:read|create|update|delete to the frontend
  Permission type (existed in backend but was absent from the frontend
  type definition).
This commit is contained in:
maziggy
2026-02-28 14:39:10 +01:00
parent 90b9523998
commit f2f43b98a3
5 changed files with 91 additions and 6 deletions
+1
View File
@@ -1998,6 +1998,7 @@ export type Permission =
| 'library:update_own' | 'library:update_all' | 'library:delete_own' | 'library:delete_all'
| 'projects:read' | 'projects:create' | 'projects:update' | 'projects:delete'
| 'filaments:read' | 'filaments:create' | 'filaments:update' | 'filaments:delete'
| 'inventory:read' | 'inventory:create' | 'inventory:update' | 'inventory:delete'
| 'smart_plugs:read' | 'smart_plugs:create' | 'smart_plugs:update' | 'smart_plugs:delete' | 'smart_plugs:control'
| 'camera:view'
| 'maintenance:read' | 'maintenance:create' | 'maintenance:update' | 'maintenance:delete'
+20 -6
View File
@@ -6,7 +6,7 @@ import { useTheme } from '../contexts/ThemeContext';
import { KeyboardShortcutsModal } from './KeyboardShortcutsModal';
import { SwitchbarPopover } from './SwitchbarPopover';
import { useQuery, useQueries } from '@tanstack/react-query';
import { api, supportApi, pendingUploadsApi } from '../api/client';
import { api, supportApi, pendingUploadsApi, type Permission } from '../api/client';
import { getIconByName } from './IconPicker';
import { useIsSidebarCompact } from '../hooks/useIsSidebarCompact';
import { useAuth } from '../contexts/AuthContext';
@@ -216,16 +216,30 @@ export function Layout() {
const extLinksMap = useMemo(() => new Map((externalLinks || []).map(link => [`ext-${link.id}`, link])), [externalLinks]);
// Compute the ordered sidebar: include stored order + any new items
// Filter out 'settings' for users with 'user' role
// Hide nav items the user doesn't have read permission for
const orderedSidebarIds = (() => {
const result: string[] = [];
const seen = new Set<string>();
// Determine if settings should be hidden (no settings:read permission)
const hideSettings = authEnabled && !hasPermission('settings:read');
// Map nav item IDs to the permission required to see them
const navPermissions: Record<string, Permission> = {
archives: 'archives:read',
queue: 'queue:read',
stats: 'stats:read',
profiles: 'kprofiles:read',
maintenance: 'maintenance:read',
projects: 'projects:read',
inventory: 'inventory:read',
files: 'library:read',
settings: 'settings:read',
};
const isHidden = (id: string) =>
authEnabled && id in navPermissions && !hasPermission(navPermissions[id]);
// Add items in stored order
for (const id of sidebarOrder) {
if (hideSettings && id === 'settings') continue;
if (isHidden(id)) continue;
if (navItemsMap.has(id) || extLinksMap.has(id)) {
result.push(id);
seen.add(id);
@@ -234,7 +248,7 @@ export function Layout() {
// Add any new internal nav items not in stored order
for (const item of defaultNavItems) {
if (hideSettings && item.id === 'settings') continue;
if (isHidden(item.id)) continue;
if (!seen.has(item.id)) {
result.push(item.id);
seen.add(item.id);