Finish fine-grained ACL across remaining admin pages and actions.

Replace leftover requireStaff gates with module PERMS, drop hardcoded room rank thresholds, and expand contract tests so admin mutations cannot regress to dashboard-only checks.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
SimoandCursor committed 2026-07-15 20:15:22 +02:00
1 parent 3c8a8ff888
commit 0e89d03940
63 files changed
+420 -163

No files matched your search

+8 -7
View File
@@ -1,7 +1,8 @@
"use server";
import { revalidatePath } from "next/cache";
import { requireStaff } from "@/lib/admin/guard";
import { requirePermission } from "@/lib/admin/guard";
import { PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
import type { ActionResult } from "@/lib/safe-action-shared";
import { rcon } from "@/lib/services/rcon";
@@ -11,7 +12,7 @@ export async function updateCatalogPage({
id,
...fields
}: { id: number } & Record<string, unknown>): Promise<ActionResult> {
const staff = await requireStaff();
const staff = await requirePermission(PERMS.CATALOG_EDIT);
await prisma.catalogPages.update({ where: { id }, data: fields as any });
await rcon.updateCatalog();
await logStaffActivity({
@@ -26,7 +27,7 @@ export async function updateCatalogPage({
}
export async function deleteCatalogPage({ id }: { id: number }) {
const staff = await requireStaff();
const staff = await requirePermission(PERMS.CATALOG_EDIT);
await prisma.catalogPages.delete({ where: { id } });
await rcon.updateCatalog();
await logStaffActivity({
@@ -47,7 +48,7 @@ export async function toggleCatalogPage({
id: number;
action: "toggleEnabled" | "toggleVisible";
}) {
await requireStaff();
await requirePermission(PERMS.CATALOG_EDIT);
const page = await prisma.catalogPages.findUnique({
where: { id },
select: { enabled: true, visible: true },
@@ -74,7 +75,7 @@ export async function createCatalogPage(input: {
minRank?: number;
orderNum?: number;
}): Promise<ActionResult<{ id: number }>> {
const staff = await requireStaff();
const staff = await requirePermission(PERMS.CATALOG_EDIT);
const created = await prisma.catalogPages.create({
data: {
caption: input.caption,
@@ -110,7 +111,7 @@ export async function reorderTreePage(input: {
newParentId?: number;
newOrderNum: number;
}) {
await requireStaff();
await requirePermission(PERMS.CATALOG_EDIT);
await prisma.catalogPages.update({
where: { id: input.pageId },
data: {
@@ -129,7 +130,7 @@ export async function deleteTreePage(input: {
pageId: number;
mode: "reparent" | "cascade";
}) {
await requireStaff();
await requirePermission(PERMS.CATALOG_EDIT);
if (input.mode === "cascade") {
const children = await prisma.catalogPages.findMany({
where: { parentId: input.pageId },