46 lines
2.6 KiB
TypeScript
46 lines
2.6 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { readFileSync } from "node:fs";
|
|
import test from "node:test";
|
|
|
|
const root = new URL("../", import.meta.url);
|
|
const adminSource = readFileSync(new URL("src/lib/supabase/admin.ts", root), "utf8");
|
|
const adminCoreSource = readFileSync(new URL("src/lib/supabase/admin-client-core.ts", root), "utf8");
|
|
const codesSource = readFileSync(new URL("src/app/api/admin/codes/route.ts", root), "utf8");
|
|
const sessionSource = readFileSync(new URL("src/app/api/admin/session/route.ts", root), "utf8");
|
|
const accountSource = readFileSync(new URL("src/app/api/account/route.ts", root), "utf8");
|
|
const usersSource = readFileSync(new URL("src/app/api/admin/users/route.ts", root), "utf8");
|
|
const migration = readFileSync(new URL("supabase/migrations/20260805020000_reconcile_payment_admin_schema.sql", root), "utf8");
|
|
|
|
test("ADMIN_EMAILS remains a case-insensitive comma-separated allowlist", () => {
|
|
assert.match(adminCoreSource, /configured/);
|
|
assert.match(adminCoreSource, /split\(","\)/);
|
|
assert.match(adminCoreSource, /toLowerCase/);
|
|
assert.match(adminCoreSource, /export function isAdminEmail/);
|
|
});
|
|
|
|
test("admin surfaces await database-backed administrator checks", () => {
|
|
assert.match(adminSource, /export async function isAdminUser/);
|
|
assert.match(adminSource, /admin_has_permission\(\$1, 'admin\.access'\)/);
|
|
assert.match(sessionSource, /await requirePermission\("admin\.access"\)/);
|
|
assert.match(codesSource, /await requireHighRiskAdminMutation\(\s*request,\s*"billing\.adjustments\.write",?\s*\)/);
|
|
assert.match(accountSource, /const isAdmin = await isAdminUser\(user\)/);
|
|
assert.match(accountSource, /isAdmin,/);
|
|
});
|
|
|
|
test("admin_users migration is service-role-only and auditable", () => {
|
|
assert.match(migration, /user_id uuid primary key references auth\.users\(id\)/);
|
|
assert.match(migration, /created_at timestamptz/);
|
|
assert.match(migration, /created_by uuid/);
|
|
assert.match(migration, /revoked_at timestamptz/);
|
|
assert.match(migration, /revoked_by uuid/);
|
|
assert.match(migration, /enable row level security/);
|
|
assert.match(migration, /revoke all on table public\.admin_users from anon, authenticated/);
|
|
assert.match(migration, /grant select, insert, update on table public\.admin_users to service_role/);
|
|
});
|
|
|
|
test("legacy admin users route aliases handlers but declares runtime statically", () => {
|
|
assert.match(usersSource, /export const runtime = "nodejs"/);
|
|
assert.match(usersSource, /export \{ DELETE, GET, PATCH, POST, PUT \} from "\.\.\/customers\/route"/);
|
|
assert.doesNotMatch(usersSource, /export \{[^}]*\bruntime\b[^}]*\} from/);
|
|
});
|