mc-dashboard/lib/use-role.ts

17 lines
450 B
TypeScript
Raw Permalink Normal View History

Role-based access: admin vs superadmin - Credentials provider now resolves two distinct accounts from env: SUPERADMIN_USERNAME / SUPERADMIN_PASSWORD → role "superadmin" ADMIN_USERNAME / ADMIN_PASSWORD → role "admin" The role is carried through the JWT and Session callbacks so the UI and API can gate on it. Types extended via types/next-auth.d.ts. - lib/auth.ts exports requireRole(minRole) and sessionRole(session). - /api/players POST rejects "op" and "deop" with 403 unless the caller is superadmin. All other player actions (whitelist add/remove, ban, pardon) remain available to both roles. - lib/use-role.ts (client hook) exposes role / isSuperadmin / authed for UI gating without duplicating session typing. - PlayerManager: Add-OP button and per-row Deop action are hidden or disabled for non-superadmin; when a regular admin is viewing the Ops tab, a banner explains the read-only state. - PlayerDrawer: Make Op / Deop button disabled with tooltip for non-superadmin; whitelist, ban, pardon unchanged. - Navbar: subtle role pill next to the user name ("Super" for superadmin amber-tinted, "Admin" for admin). - Migration note: the existing ADMIN_* credentials now log in as the restricted admin role. Set SUPERADMIN_USERNAME + SUPERADMIN_PASSWORD in .env.local to retain operator-management ability. A placeholder superadmin account was generated in .env.local; the password is in the commit terminal output only, not the repo. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 06:52:05 -06:00
"use client";
import { useSession } from "next-auth/react";
export type Role = "admin" | "superadmin";
export function useRole(): { role: Role | null; isSuperadmin: boolean; authed: boolean } {
const { data: session, status } = useSession();
const role =
(session?.user as { role?: Role } | undefined)?.role ?? null;
return {
role,
isSuperadmin: role === "superadmin",
authed: status === "authenticated" && !!session,
};
}