import { createClient } from '@supabase/supabase-js'; import { Client, ClientConfig } from 'pg'; import * as dotenv from 'dotenv'; // Load environment variables from .env file dotenv.config(); const SUPABASE_URL = process.env.SUPABASE_URL || 'https://ffbgowwvcqmdtvvabmnh.supabase.co'; // Try SUPABASE_SERVICE_ROLE_KEY first, then fall back to SUPABASE_SECRET_KEY const SUPABASE_SERVICE_ROLE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_SECRET_KEY || ''; // Target database configuration (Supabase) const targetConfig: ClientConfig = { host: 'aws-1-us-east-1.pooler.supabase.com', port: 6543, database: 'postgres', user: 'postgres.ffbgowwvcqmdtvvabmnh', password: '!a_KW.-6Grb-X?#', ssl: { rejectUnauthorized: false }, }; interface UserIdentity { id: string; user_profile_id: string; provider: string; email: string; } async function createSupabaseUsers() { if (!SUPABASE_SERVICE_ROLE_KEY) { console.error('Error: SUPABASE_SERVICE_ROLE_KEY environment variable is required'); console.log(''); console.log('To get your service role key:'); console.log('1. Go to https://supabase.com/dashboard/project/ffbgowwvcqmdtvvabmnh/settings/api'); console.log('2. Copy the "service_role" key (under "Project API keys")'); console.log('3. Run: SUPABASE_SERVICE_ROLE_KEY="your-key" npx tsx scripts/create-supabase-users.ts'); process.exit(1); } const supabase = createClient(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, { auth: { autoRefreshToken: false, persistSession: false, }, }); const pgClient = new Client(targetConfig); try { console.log('Connecting to Supabase database...'); await pgClient.connect(); console.log('Connected!'); // Get all email users from user_identities const result = await pgClient.query(` SELECT id, user_profile_id, provider, email FROM user_identities WHERE provider = 'email' `); console.log(`\nFound ${result.rows.length} email users to migrate:\n`); const results: { email: string; success: boolean; error?: string; authUserId?: string }[] = []; for (const user of result.rows) { console.log(`Processing: ${user.email}`); try { // Check if user already exists in Supabase Auth const { data: existingUsers } = await supabase.auth.admin.listUsers(); const existingUser = existingUsers?.users.find((u) => u.email === user.email); let authUserId: string; if (existingUser) { console.log(` User already exists in Supabase Auth: ${existingUser.id}`); authUserId = existingUser.id; } else { // Create new user with a temporary password // Users will need to reset their password const tempPassword = `Temp${Math.random().toString(36).slice(2)}!${Date.now()}`; const { data: newUser, error: createError } = await supabase.auth.admin.createUser({ email: user.email, password: tempPassword, email_confirm: true, // Auto-confirm email }); if (createError) { throw new Error(createError.message); } if (!newUser?.user) { throw new Error('No user returned from createUser'); } authUserId = newUser.user.id; console.log(` Created new Supabase Auth user: ${authUserId}`); } // Update user_profiles with supabase_user_id await pgClient.query( `UPDATE user_profiles SET supabase_user_id = $1 WHERE id = $2`, [authUserId, user.user_profile_id] ); console.log(` Updated user_profiles.supabase_user_id`); // Update user_identities with provider_id await pgClient.query( `UPDATE user_identities SET provider_id = $1 WHERE id = $2`, [authUserId, user.id] ); console.log(` Updated user_identities.provider_id`); // Generate password reset link (optional - for sending to users) const { data: resetLink, error: resetError } = await supabase.auth.admin.generateLink({ type: 'recovery', email: user.email, }); if (resetLink && !resetError) { console.log(` Password reset link generated`); } results.push({ email: user.email, success: true, authUserId }); console.log(` ✓ Completed\n`); } catch (error: any) { console.log(` ✗ Failed: ${error.message}\n`); results.push({ email: user.email, success: false, error: error.message }); } } // Print summary console.log('\n========================================'); console.log('Supabase Auth User Creation Summary:'); console.log('========================================'); const successful = results.filter((r) => r.success); const failed = results.filter((r) => !r.success); console.log(`\nSuccessful: ${successful.length}`); for (const r of successful) { console.log(` ✓ ${r.email} -> ${r.authUserId}`); } if (failed.length > 0) { console.log(`\nFailed: ${failed.length}`); for (const r of failed) { console.log(` ✗ ${r.email}: ${r.error}`); } } console.log('\n========================================'); console.log('\nNote: All users have been created with temporary passwords.'); console.log('They will need to use "Forgot Password" to set a new password.'); console.log('========================================\n'); } catch (error: any) { console.error('Error:', error.message); throw error; } finally { await pgClient.end(); } } createSupabaseUsers().catch(console.error);