fix(admin): restore sidebar categories via ACL grant repair
Deploy / release (push) Skipped
Deploy / deploy (push) Successful in 1m49s

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
SimoandCursor committed 2026-07-22 21:47:23 +02:00
1 parent ce6e8235cc
commit 255c09b9fd
3 files changed
+94 -4

No files matched your search

+14 -4
View File
@@ -12,7 +12,7 @@ import { ThemeSwitcher } from "@/components/theme-switcher";
import { requireStaff } from "@/lib/admin/guard";
import { collectNavPermissionSlugs } from "@/lib/admin-nav";
import { setCsrfCookie } from "@/lib/foundation/security";
import { canAccess, getAdminContext } from "@/lib/permissions";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
import { siteSettings } from "@/lib/services/site-settings";
@@ -70,11 +70,21 @@ async function Sidebar({
const initial = staff.username.charAt(0).toUpperCase();
const { permissions } = await getAdminContext();
const isSuperAdmin = permissions.isSuperAdmin;
const hasDashboard = canAccess(
permissions,
PERMS.ADMIN_DASHBOARD,
staff.rank,
);
// Super-admins see everything. Everyone else sees items their ACL grants.
// If they can open the admin panel but ACL is incomplete (common after HK→ACL
// migration gaps), still show *.view nav entries so categories do not vanish.
const allowedPermissions = isSuperAdmin
? []
: collectNavPermissionSlugs().filter((slug) =>
canAccess(permissions, slug, staff.rank),
);
: collectNavPermissionSlugs().filter((slug) => {
if (canAccess(permissions, slug, staff.rank)) return true;
if (!hasDashboard) return false;
return slug.endsWith(".view") || slug === PERMS.ADMIN_DASHBOARD;
});
return (
<aside
@@ -31,4 +31,15 @@ describe("production ACL migration", () => {
expect(seedSql).toContain("ap.slug = 'admin.dashboard'");
expect(seedSql).toContain("ap.slug = 'mod.dashboard'");
});
it("repairs full admin.* grants for ranks that already have dashboard", () => {
const repairSql = readFileSync(
resolve(migrationsDir, "0018_acl_repair_admin_nav_grants.sql"),
"utf8",
);
expect(repairSql).toContain("admin.dashboard");
expect(repairSql).toContain("ap.slug LIKE 'admin.%'");
expect(repairSql).toContain("pr.id >= 6");
expect(repairSql).toContain("pr.id >= 7");
});
});