import { createClient } from 'https://esm.sh/@supabase/supabase-js@2.57.4' const cors = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type', 'Access-Control-Allow-Methods': 'POST, OPTIONS', } const json = (body: unknown, status = 200) => new Response(JSON.stringify(body), {status, headers:{...cors,'Content-Type':'application/json'}}) Deno.serve(async (req) => { if (req.method === 'OPTIONS') return new Response('ok', {headers:cors}) if (req.method !== 'POST') return json({error:'Method not allowed'},405) try { const url = Deno.env.get('SUPABASE_URL')! const anon = Deno.env.get('SUPABASE_ANON_KEY')! const service = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')! const authHeader = req.headers.get('Authorization') || '' const userClient = createClient(url, anon, {global:{headers:{Authorization:authHeader}},auth:{persistSession:false,autoRefreshToken:false}}) const {data:{user},error:userError} = await userClient.auth.getUser() if (userError || !user) return json({error:'Unauthorized'},401) const {data:isAdmin,error:adminError} = await userClient.rpc('sun_is_platform_admin') if (adminError || isAdmin !== true) return json({error:'Platform administrator required'},403) const body = await req.json().catch(()=>({})) as Record const action = String(body.action || 'list') const admin = createClient(url, service, {auth:{persistSession:false,autoRefreshToken:false}}) if (action === 'list') { const users:any[] = [] for (let page=1; page<=20; page++) { const {data,error} = await admin.auth.admin.listUsers({page,perPage:1000}) if (error) throw error users.push(...(data.users||[])) if ((data.users||[]).length < 1000) break } const {data:directory,error:dirError} = await userClient.rpc('sun_platform_list_users') if (dirError) throw dirError const byId = new Map() for (const row of (directory||[])) { const id=String(row.user_id) if(!byId.has(id))byId.set(id,{is_platform_admin:row.is_platform_admin===true,workspaces:[]}) if(row.workspace_id)byId.get(id).workspaces.push({id:row.workspace_id,name:row.workspace_name,role:row.role,display_name:row.display_name,is_active:row.is_active!==false}) } return json({users:users.map(u=>({ id:u.id,email:u.email||'',created_at:u.created_at||'',last_sign_in_at:u.last_sign_in_at||'', email_confirmed_at:u.email_confirmed_at||u.confirmed_at||'',banned_until:u.banned_until||'', is_banned:Boolean(u.banned_until&&new Date(u.banned_until)>new Date()), is_platform_admin:byId.get(String(u.id))?.is_platform_admin===true, workspaces:byId.get(String(u.id))?.workspaces||[] }))}) } const targetId = String(body.user_id || '') if (!targetId) return json({error:'user_id required'},400) if (targetId === user.id && action === 'set_ban') return json({error:'Нельзя заблокировать собственный аккаунт разработчика.'},400) const {data:{user:target},error:targetError}=await admin.auth.admin.getUserById(targetId) if(targetError||!target)return json({error:'User not found'},404) if (action === 'set_ban') { const banned = body.banned === true const {error}=await admin.auth.admin.updateUserById(targetId,{ban_duration:banned?'876000h':'none'}) if(error)throw error await userClient.rpc('sun_platform_log_event',{p_action:banned?'account.ban':'account.unban',p_workspace:null,p_user:targetId,p_details:{email:target.email||''}}) return json({ok:true,banned}) } if (action === 'send_recovery') { if(!target.email)return json({error:'У пользователя нет email.'},400) const publicClient=createClient(url,anon,{auth:{persistSession:false,autoRefreshToken:false}}) const {error}=await publicClient.auth.resetPasswordForEmail(target.email) if(error)throw error await userClient.rpc('sun_platform_log_event',{p_action:'account.recovery_sent',p_workspace:null,p_user:targetId,p_details:{email:target.email}}) return json({ok:true}) } return json({error:'Unknown action'},400) } catch (e) { console.error(e) return json({error:e instanceof Error?e.message:String(e)},500) } })