Files
vyndr/web/src/lib/isAdmin.ts
T

27 lines
983 B
TypeScript

/**
* Admin allowlist (Session 18).
*
* Server-side check ONLY. The client-side `useAuth()` redirect on
* `/admin` is for UX (so non-admins don't see a 401 screen) — the
* security boundary lives in `/api/admin/stats/route.ts`, which calls
* this helper against the bearer token's email before returning any
* data. Anyone can spoof a client-side check; they can't spoof the
* Supabase token verification on the server.
*
* To add an admin: append their email here. Lowercase. The check is
* case-insensitive on inputs but the registry is canonical.
*/
const ADMIN_EMAILS: ReadonlySet<string> = new Set([
'kevdevelops@gmail.com',
]);
export function isAdmin(email: string | null | undefined): boolean {
if (!email) return false;
return ADMIN_EMAILS.has(String(email).trim().toLowerCase());
}
// Exported for tests + the rare debug page that wants to show how
// many admins are configured without enumerating them.
export const adminCount = ADMIN_EMAILS.size;