import { createClient } from 'https://esm.sh/@supabase/supabase-js@2.57.4'; const corsHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type', }; const supabaseUrl = Deno.env.get('SUPABASE_URL')!; const supabaseServiceKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!; Deno.serve(async (req) => { if (req.method === 'OPTIONS') { return new Response(null, { headers: corsHeaders }); } try { const { challengeId, factorId, code, userId } = await req.json(); if (!challengeId || !factorId || !code || !userId) { return new Response( JSON.stringify({ error: 'Missing required fields' }), { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } } ); } // Create admin client const supabaseAdmin = createClient(supabaseUrl, supabaseServiceKey, { auth: { autoRefreshToken: false, persistSession: false, }, }); // Verify TOTP code const { data: verifyData, error: verifyError } = await supabaseAdmin.auth.mfa.verify({ factorId, challengeId, code, }); if (verifyError || !verifyData) { console.error('MFA verification error:', verifyError); return new Response( JSON.stringify({ error: verifyError?.message || 'Invalid verification code' }), { status: 401, headers: { ...corsHeaders, 'Content-Type': 'application/json' } } ); } // Verification successful - create AAL2 session using admin API const { data: sessionData, error: sessionError } = await supabaseAdmin.auth.admin.createSession({ userId, // This creates a session with AAL2 }); if (sessionError || !sessionData) { console.error('Session creation error:', sessionError); return new Response( JSON.stringify({ error: 'Failed to create session' }), { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } } ); } // Log successful MFA authentication try { await supabaseAdmin.rpc('log_admin_action', { _admin_user_id: userId, _target_user_id: userId, _action: 'mfa_login_success', _details: { timestamp: new Date().toISOString(), aal: 'aal2' }, }); } catch (logError) { console.error('Audit log error:', logError); // Don't fail the login if audit logging fails } return new Response( JSON.stringify({ success: true, session: sessionData.session, user: sessionData.user, }), { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } } ); } catch (error) { console.error('Unexpected error:', error); return new Response( JSON.stringify({ error: 'Internal server error' }), { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } } ); } });