import { existsSync, readFileSync, readdirSync } from "node:fs"; import { join, relative } from "node:path"; import { describe, expect, it } from "vitest"; const ROUTES: Array<[string, string]> = [ ["moderation", "PERMS.MODERATION_VIEW"], ["moderation/actions", "PERMS.MODERATION_EDIT"], ["moderation/cfh", "PERMS.MODERATION_VIEW"], ["logs/audit", "PERMS.LOGS_VIEW"], ["analytics", "PERMS.ANALYTICS_VIEW"], ["devops", "PERMS.DEVOPS_VIEW"], ["online", "PERMS.USERS_VIEW"], ["commandocentrum", "PERMS.RCON_EXECUTE"], ["users/edit/[id]", "PERMS.USERS_EDIT"], ["settings", "PERMS.SETTINGS_VIEW"], ["theme", "PERMS.SETTINGS_VIEW"], ["emulator", "PERMS.SETTINGS_VIEW"], ["bans", "PERMS.BANS_VIEW"], ["wordfilter", "PERMS.WORDFILTER_VIEW"], ["articles", "PERMS.NEWS_VIEW"], ["shop", "PERMS.SHOP_VIEW"], ["transactions", "PERMS.SHOP_VIEW"], ["vouchers", "PERMS.SHOP_VIEW"], ["vpn", "PERMS.SETTINGS_VIEW"], ["ip", "PERMS.SETTINGS_VIEW"], ["maintenance", "PERMS.SETTINGS_VIEW"], ["alerts", "PERMS.NOTIFICATIONS_VIEW"], ["tags", "PERMS.PAGES_VIEW"], ["ads", "PERMS.PAGES_VIEW"], ["media", "PERMS.PAGES_VIEW"], ["photos", "PERMS.PAGES_VIEW"], ["badges", "PERMS.CATALOG_VIEW"], ["teams", "PERMS.USERS_VIEW"], ["applications", "PERMS.USERS_VIEW"], ["logs", "PERMS.LOGS_VIEW"], ["catalog", "PERMS.CATALOG_VIEW"], ["rooms/edit/[id]", "PERMS.ROOMS_EDIT"], ]; const ACTION_GATES: Array<[string, string]> = [ ["admin-settings.ts", "PERMS.SETTINGS_EDIT"], ["admin-theme.ts", "PERMS.SETTINGS_EDIT"], ["admin-emulator.ts", "PERMS.SETTINGS_EDIT"], ["admin-bans.ts", "PERMS.USERS_BAN"], ["admin-wordfilter.ts", "PERMS.WORDFILTER_EDIT"], ["admin-articles.ts", "PERMS.NEWS_EDIT"], ["admin-shop.ts", "PERMS.SHOP_EDIT"], ["admin-radio-autodj.ts", "PERMS.RADIO_EDIT"], ["catalog.ts", "PERMS.CATALOG_EDIT"], ["rooms.ts", "PERMS.ROOMS_EDIT"], ["admin-vpn.ts", "PERMS.SETTINGS_EDIT"], ["admin-ads.ts", "PERMS.PAGES_EDIT"], ["admin-vouchers.ts", "PERMS.SHOP_EDIT"], ["admin-alerts.ts", "PERMS.NOTIFICATIONS_EDIT"], ["commandocentrum.ts", "PERMS.RCON_EXECUTE"], ["translations.ts", "PERMS.SETTINGS_EDIT"], ]; describe("admin operations route contract", () => { it.each(ROUTES)("provides and guards /admin/%s", (route, permission) => { const path = `src/app/admin/${route}/page.tsx`; expect(existsSync(path), path).toBe(true); expect(readFileSync(path, "utf8"), path).toContain(permission); }); it("guards radio section via layout", () => { const path = "src/app/admin/radio/layout.tsx"; expect(existsSync(path), path).toBe(true); expect(readFileSync(path, "utf8"), path).toContain("PERMS.RADIO_VIEW"); }); it.each([ ["analytics/export", "PERMS.ANALYTICS_EXPORT"], ["devops/health", "PERMS.DEVOPS_VIEW"], ["users/actions", "PERMS.USERS_EDIT"], ])("provides and guards /api/admin/%s", (route, permission) => { const path = `src/app/api/admin/${route}/route.ts`; expect(existsSync(path), path).toBe(true); expect(readFileSync(path, "utf8"), path).toContain(permission); }); it.each(ACTION_GATES)("guards %s with %s", (file, permission) => { const source = readFileSync(`src/actions/${file}`, "utf8"); expect(source).toContain(permission); expect(source).not.toMatch(/await requireStaff\(\)/); expect(source).not.toMatch(/await requireStaffRateLimited\(\)/); }); it("has no requireStaff left in admin action modules", () => { const dir = "src/actions"; const offenders: string[] = []; for (const name of readdirSync(dir)) { if (!name.endsWith(".ts") || name.endsWith(".test.ts")) continue; const source = readFileSync(join(dir, name), "utf8"); if (/await requireStaff(RateLimited)?\(\)/.test(source)) { offenders.push(name); } } expect(offenders).toEqual([]); }); it("has no requireStaff left in admin pages", () => { const root = "src/app/admin"; const offenders: string[] = []; function walk(dir: string) { for (const entry of readdirSync(dir, { withFileTypes: true })) { const full = join(dir, entry.name); if (entry.isDirectory()) walk(full); else if (entry.name === "page.tsx") { const source = readFileSync(full, "utf8"); if (/await requireStaff\(/.test(source)) { offenders.push(relative(process.cwd(), full).replaceAll("\\", "/")); } } } } walk(root); expect(offenders).toEqual([]); }); });