CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history
promote-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 | * Promote a user to site admin. | |
| 3 | * | |
| 4 | * Usage: | |
| 5 | * docker compose exec gluecron bun run scripts/promote-admin.ts <email> | |
| 6 | * | |
| 7 | * Sets both `users.is_admin = true` AND inserts into `site_admins`, so the | |
| 8 | * account is admin under both the bootstrap rule and the explicit-list rule. | |
| 9 | * | |
| 10 | * Idempotent: safe to re-run. Reports what changed. | |
| 11 | */ | |
| 12 | import { db } from "../src/db/client"; | |
| 13 | import { users, siteAdmins } from "../src/db/schema"; | |
| 14 | import { and, eq } from "drizzle-orm"; | |
| 15 | ||
| 16 | const emailArg = process.argv[2]; | |
| 17 | if (!emailArg) { | |
| 18 | console.error("Usage: bun run scripts/promote-admin.ts <email>"); | |
| 19 | process.exit(2); | |
| 20 | } | |
| 21 | const email = emailArg.toLowerCase().trim(); | |
| 22 | ||
| 23 | const userRow = await db | |
| 24 | .select({ id: users.id, email: users.email, isAdmin: users.isAdmin }) | |
| 25 | .from(users) | |
| 26 | .where(eq(users.email, email)) | |
| 27 | .limit(1); | |
| 28 | ||
| 29 | if (userRow.length === 0) { | |
| 30 | console.error(`No user found for email: ${email}`); | |
| 31 | console.error("Register at /register first, then re-run this script."); | |
| 32 | process.exit(1); | |
| 33 | } | |
| 34 | const u = userRow[0]; | |
| 35 | ||
| 36 | let flippedIsAdmin = false; | |
| 37 | if (!u.isAdmin) { | |
| 38 | await db.update(users).set({ isAdmin: true }).where(eq(users.id, u.id)); | |
| 39 | flippedIsAdmin = true; | |
| 40 | } | |
| 41 | ||
| 42 | const existing = await db | |
| 43 | .select({ userId: siteAdmins.userId }) | |
| 44 | .from(siteAdmins) | |
| 45 | .where(eq(siteAdmins.userId, u.id)) | |
| 46 | .limit(1); | |
| 47 | ||
| 48 | let insertedSiteAdmin = false; | |
| 49 | if (existing.length === 0) { | |
| 50 | await db.insert(siteAdmins).values({ userId: u.id, grantedBy: u.id }); | |
| 51 | insertedSiteAdmin = true; | |
| 52 | } | |
| 53 | ||
| 54 | console.log(`User: ${u.email} (${u.id})`); | |
| 55 | console.log(` users.is_admin : ${flippedIsAdmin ? "flipped FALSE -> TRUE" : "already TRUE"}`); | |
| 56 | console.log(` site_admins row : ${insertedSiteAdmin ? "INSERTED" : "already present"}`); | |
| 57 | console.log(""); | |
| 58 | console.log("✓ This account is now a site admin. Log out and back in if /admin still 403s."); |