import { createClient } from "https://esm.sh/@supabase/supabase-js@2"; const corsHeaders = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type", }; Deno.serve(async (req) => { if (req.method === "OPTIONS") { return new Response("ok", { headers: corsHeaders, }); } try { const authHeader = req.headers.get("Authorization"); if (!authHeader) { return new Response( JSON.stringify({ error: "Missing authorization" }), { status: 401, headers: { ...corsHeaders, "Content-Type": "application/json", }, } ); } const supabaseUrl = Deno.env.get("SUPABASE_URL")!; const anonKey = Deno.env.get("SUPABASE_ANON_KEY")!; const serviceRoleKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!; const supabase = createClient( supabaseUrl, anonKey, { global: { headers: { Authorization: authHeader, }, }, } ); const { data: { user: adminUser }, error: authError, } = await supabase.auth.getUser(); if (authError || !adminUser) { return new Response( JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { ...corsHeaders, "Content-Type": "application/json", }, } ); } const { data: adminProfile, error: profileError } = await supabase .from("profiles") .select("role,status") .eq("id", adminUser.id) .single(); if ( profileError || !adminProfile || adminProfile.role !== "admin" || adminProfile.status !== "active" ) { return new Response( JSON.stringify({ error: "Admin access required" }), { status: 403, headers: { ...corsHeaders, "Content-Type": "application/json", }, } ); } const body = await req.json(); const email = String(body.email || "") .trim() .toLowerCase(); const password = String(body.password || ""); if (!email || !password) { return new Response( JSON.stringify({ error: "Email and password are required", }), { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json", }, } ); } if (password.length < 6) { return new Response( JSON.stringify({ error: "Password must contain at least 6 characters", }), { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json", }, } ); } const adminClient = createClient( supabaseUrl, serviceRoleKey ); const { data: newUser, error: createError, } = await adminClient.auth.admin.createUser({ email, password, email_confirm: true, }); if (createError) { return new Response( JSON.stringify({ error: createError.message, }), { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json", }, } ); } const { error: profileCreateError } = await adminClient .from("profiles") .upsert({ id: newUser.user.id, email, role: "user", status: "active", }); if (profileCreateError) { await adminClient.auth.admin.deleteUser( newUser.user.id ); return new Response( JSON.stringify({ error: profileCreateError.message, }), { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json", }, } ); } const { error: walletError } = await adminClient .from("wallets") .insert({ user_id: newUser.user.id, balance: 0, }); if (walletError && walletError.code !== "23505") { return new Response( JSON.stringify({ error: walletError.message, }), { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json", }, } ); } return new Response( JSON.stringify({ success: true, user: { id: newUser.user.id, email: newUser.user.email, }, }), { status: 200, headers: { ...corsHeaders, "Content-Type": "application/json", }, } ); } catch (error) { return new Response( JSON.stringify({ error: error instanceof Error ? error.message : "Unexpected error", }), { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json", }, } ); } });