import { existsSync, readdirSync, readFileSync } from "node:fs"; import { join } from "node:path"; import { describe, expect, it } from "vitest"; const ACTION_GATES: Array<[string, string]> = [ ["admin-bans.ts", "PERMS.USERS_BAN"], ["admin-wordfilter.ts", "PERMS.WORDFILTER_EDIT"], ["admin-articles.ts", "PERMS.NEWS_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-alerts.ts", "PERMS.NOTIFICATIONS_EDIT"], ["tickets.ts", "PERMS.TICKETS_EDIT"], ["admin-help-tickets.ts", "PERMS.TICKETS_EDIT"], ["permissions.ts", "PERMS.PERMISSIONS_MANAGE"], ["permissions.ts", "repairAdminNavAclGrants"], ["admin-guilds.ts", "PERMS.USERS_EDIT"], ["moderation.ts", "PERMS.MODERATION_EDIT"], ]; describe("administration backend contract", () => { 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("requires explicit permissions for every administration action", () => { 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("keeps the shared ops health probe behind the API", () => { expect(existsSync("src/lib/admin/ops-health.ts")).toBe(true); expect( readFileSync("src/app/api/admin/devops/health/route.ts", "utf8"), ).toContain("fetchOpsHealth"); }); });