// Grant or revoke a role for a user by phone number (US +1 assumed). // Usage: bun run scripts/make-admin.ts [--role Admin|Developer] [--revoke] import "dotenv/config"; import SuperTokens from "supertokens-node"; import Session from "supertokens-node/recipe/session"; import Passwordless from "supertokens-node/recipe/passwordless"; import UserRoles from "supertokens-node/recipe/userroles"; SuperTokens.init({ framework: "custom", supertokens: { connectionURI: process.env.SUPERTOKENS_URI || "http://localhost:3567", apiKey: process.env.SUPERTOKENS_API_KEY || undefined, }, appInfo: { appName: "FLXN", apiDomain: "http://localhost:3000", websiteDomain: "http://localhost:3000", apiBasePath: "/api/auth", websiteBasePath: "/auth", }, recipeList: [ Passwordless.init({ contactMethod: "PHONE", flowType: "USER_INPUT_CODE" }), Session.init(), UserRoles.init(), ], }); const VALID_ROLES = ["Admin", "Developer"] as const; const raw = process.argv[2]; const revoke = process.argv.includes("--revoke"); const roleFlagIndex = process.argv.indexOf("--role"); const role = roleFlagIndex === -1 ? "Admin" : process.argv[roleFlagIndex + 1]; if (!raw) { console.error("Usage: bun run scripts/make-admin.ts [--role Admin|Developer] [--revoke]"); process.exit(1); } if (!VALID_ROLES.includes(role as (typeof VALID_ROLES)[number])) { console.error(`Invalid role "${role}". Valid roles: ${VALID_ROLES.join(", ")}`); process.exit(1); } const digits = raw.replace(/[^\d]/g, ""); const candidates = Array.from( new Set([ raw.startsWith("+") ? raw : null, digits.length === 10 ? `+1${digits}` : null, `+${digits}`, digits, ].filter(Boolean) as string[]) ); let user: { id: string } | undefined; let matched = ""; for (const phoneNumber of candidates) { const users = await SuperTokens.listUsersByAccountInfo("public", { phoneNumber }); if (users.length) { user = users[0]; matched = phoneNumber; break; } } if (!user) { console.error(`No SuperTokens user found for phone (tried: ${candidates.join(", ")}).`); console.error("The user must have logged in at least once so their account exists."); process.exit(1); } await UserRoles.createNewRoleOrAddPermissions(role, []); if (revoke) { const res = await UserRoles.removeUserRole("public", user.id, role); console.log(`Removed ${role} from ${matched} (user ${user.id}):`, res.status); } else { const res = await UserRoles.addRoleToUser("public", user.id, role); console.log( `Granted ${role} to ${matched} (user ${user.id}):`, res.status === "OK" ? res.didUserAlreadyHaveRole ? "already had it" : "added" : res.status ); } console.log("Note: sign out and back in (or refresh the session) for the role to take effect."); process.exit(0);