File size: 4,057 Bytes
7f88bdf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | #!/usr/bin/env node
/**
* Script to set a user as superuser
* Usage: node scripts/set-superuser.mjs <user-email>
*/
import { createClient } from "@supabase/supabase-js";
import { readFileSync } from "fs";
import { fileURLToPath } from "url";
import { dirname, join } from "path";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Simple env file parser
function loadEnv(path) {
try {
const content = readFileSync(path, "utf-8");
const env = {};
for (const line of content.split("\n")) {
const match = line.match(/^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);
if (match) {
const key = match[1];
let value = match[2].trim();
// Remove quotes if present
if ((value.startsWith('"') && value.endsWith('"')) ||
(value.startsWith("'") && value.endsWith("'"))) {
value = value.slice(1, -1);
}
env[key] = value;
}
}
return env;
} catch (e) {
return {};
}
}
const env = loadEnv(join(__dirname, "../apps/web/.env.local"));
const supabaseUrl = env.NEXT_PUBLIC_SUPABASE_URL || process.env.NEXT_PUBLIC_SUPABASE_URL;
const supabaseServiceKey = env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_SERVICE_ROLE_KEY;
if (!supabaseUrl || !supabaseServiceKey) {
console.error("Missing required environment variables:");
console.error(" - NEXT_PUBLIC_SUPABASE_URL");
console.error(" - SUPABASE_SERVICE_ROLE_KEY");
process.exit(1);
}
const email = process.argv[2];
if (!email) {
console.error("Usage: node scripts/set-superuser.mjs <user-email>");
process.exit(1);
}
const supabase = createClient(supabaseUrl, supabaseServiceKey);
async function main() {
// Find user by email
const { data: { users }, error: listError } = await supabase.auth.admin.listUsers();
if (listError) {
console.error("Failed to list users:", listError.message);
process.exit(1);
}
const user = users.find((u) => u.email === email);
if (!user) {
console.error(`User with email "${email}" not found`);
process.exit(1);
}
console.log(`Found user: ${user.id} (${user.email})`);
// Find or create member record
let { data: member } = await supabase
.from("members")
.select("*, organizations(id, name)")
.eq("user_id", user.id)
.single();
if (!member) {
console.log("No member record found. Creating organization and membership...");
// Create organization
const slug = `org-${user.id.slice(0, 8)}`;
const orgName = email.split("@")[0] || "Admin Organization";
const { data: org, error: orgErr } = await supabase
.from("organizations")
.insert({ name: orgName, slug })
.select("id")
.single();
if (orgErr) {
console.error("Failed to create organization:", orgErr.message);
process.exit(1);
}
console.log(`Created organization: ${org.id}`);
// Create member record as superuser
const { data: newMember, error: memberErr } = await supabase
.from("members")
.insert({
organization_id: org.id,
user_id: user.id,
role: "owner",
is_superuser: true
})
.select("*")
.single();
if (memberErr) {
console.error("Failed to create member:", memberErr.message);
process.exit(1);
}
member = newMember;
console.log(`Created member record with superuser privileges`);
}
// Update to superuser if not already
if (member.is_superuser) {
console.log(`✓ ${email} is already a superuser`);
return;
}
const { error: updateError } = await supabase
.from("members")
.update({ is_superuser: true })
.eq("user_id", user.id);
if (updateError) {
console.error("Failed to update member:", updateError.message);
process.exit(1);
}
console.log(`✓ Successfully set ${email} as superuser`);
console.log("You can now access /admin with this account");
}
main().catch((err) => {
console.error("Unexpected error:", err);
process.exit(1);
});
|