CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history
check-admin.ts
Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.
| e6f7b90 | 1 | /** |
| 2 | * Check whether a user is a site admin. | |
| 3 | * | |
| 4 | * Usage: | |
| 5 | * docker compose exec gluecron bun run scripts/check-admin.ts <email> | |
| 6 | * | |
| 7 | * Reports both `users.is_admin` and `site_admins` table presence so you can | |
| 8 | * see if your account is admin-promoted at either level. Use | |
| 9 | * `scripts/promote-admin.ts` to grant admin if it isn't. | |
| 10 | */ | |
| 11 | import { db } from "../src/db/client"; | |
| 12 | import { users, siteAdmins } from "../src/db/schema"; | |
| 13 | import { eq } from "drizzle-orm"; | |
| 14 | ||
| 15 | const emailArg = process.argv[2]; | |
| 16 | if (!emailArg) { | |
| 17 | console.error("Usage: bun run scripts/check-admin.ts <email>"); | |
| 18 | process.exit(2); | |
| 19 | } | |
| 20 | const email = emailArg.toLowerCase().trim(); | |
| 21 | ||
| 22 | const userRow = await db | |
| 23 | .select({ id: users.id, email: users.email, isAdmin: users.isAdmin, createdAt: users.createdAt }) | |
| 24 | .from(users) | |
| 25 | .where(eq(users.email, email)) | |
| 26 | .limit(1); | |
| 27 | ||
| 28 | if (userRow.length === 0) { | |
| 29 | console.error(`No user found for email: ${email}`); | |
| 30 | console.error("Register at /register first, then re-run this script."); | |
| 31 | process.exit(1); | |
| 32 | } | |
| 33 | ||
| 34 | const u = userRow[0]; | |
| 35 | const inSiteAdmins = await db | |
| 36 | .select({ userId: siteAdmins.userId }) | |
| 37 | .from(siteAdmins) | |
| 38 | .where(eq(siteAdmins.userId, u.id)) | |
| 39 | .limit(1); | |
| 40 | ||
| 41 | const totalSiteAdmins = await db.select({ userId: siteAdmins.userId }).from(siteAdmins); | |
| 42 | ||
| 43 | console.log(`User: ${u.email}`); | |
| 44 | console.log(` id: ${u.id}`); | |
| 45 | console.log(` created_at: ${u.createdAt.toISOString()}`); | |
| 46 | console.log(` users.is_admin: ${u.isAdmin ? "YES" : "no"}`); | |
| 47 | console.log(` in site_admins: ${inSiteAdmins.length > 0 ? "YES" : "no"}`); | |
| 48 | console.log(` total site_admins: ${totalSiteAdmins.length}`); | |
| 49 | ||
| 50 | if (totalSiteAdmins.length === 0) { | |
| 51 | console.log(""); | |
| 52 | console.log("site_admins table is empty — the bootstrap rule applies:"); | |
| 53 | console.log(" the oldest user in `users` is treated as admin by app code."); | |
| 54 | console.log(" Run scripts/promote-admin.ts to make this explicit and durable."); | |
| 55 | } | |
| 56 | ||
| 57 | if (u.isAdmin && inSiteAdmins.length > 0) { | |
| 58 | console.log(""); | |
| 59 | console.log("✓ This account is a full site admin."); | |
| 60 | process.exit(0); | |
| 61 | } | |
| 62 | ||
| 63 | if (u.isAdmin || inSiteAdmins.length > 0) { | |
| 64 | console.log(""); | |
| 65 | console.log("~ Partial admin state. Run scripts/promote-admin.ts to normalise."); | |
| 66 | process.exit(0); | |
| 67 | } | |
| 68 | ||
| 69 | console.log(""); | |
| 70 | console.log("× This account is NOT admin. Run:"); | |
| 71 | console.log(` docker compose exec gluecron bun run scripts/promote-admin.ts ${email}`); | |
| 72 | process.exit(0); |