import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'; 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', }; serve(async (req) => { if (req.method === 'OPTIONS') { return new Response(null, { headers: corsHeaders }); } try { const supabaseClient = createClient( Deno.env.get('SUPABASE_URL') ?? '', Deno.env.get('SUPABASE_ANON_KEY') ?? '', { global: { headers: { Authorization: req.headers.get('Authorization')! }, }, } ); // Get authenticated user const { data: { user }, error: userError, } = await supabaseClient.auth.getUser(); if (userError || !user) { throw new Error('Unauthorized'); } console.log(`Processing deletion request for user: ${user.id}`); // Check for existing pending deletion request const { data: existingRequest } = await supabaseClient .from('account_deletion_requests') .select('*') .eq('user_id', user.id) .eq('status', 'pending') .maybeSingle(); if (existingRequest) { return new Response( JSON.stringify({ error: 'You already have a pending deletion request', request: existingRequest, }), { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' }, } ); } // Generate confirmation code const { data: codeData, error: codeError } = await supabaseClient .rpc('generate_deletion_confirmation_code'); if (codeError) { throw codeError; } const confirmationCode = codeData as string; const scheduledDeletionAt = new Date(); scheduledDeletionAt.setDate(scheduledDeletionAt.getDate() + 14); // Create deletion request const { data: deletionRequest, error: requestError } = await supabaseClient .from('account_deletion_requests') .insert({ user_id: user.id, confirmation_code: confirmationCode, confirmation_code_sent_at: new Date().toISOString(), scheduled_deletion_at: scheduledDeletionAt.toISOString(), status: 'pending', }) .select() .single(); if (requestError) { throw requestError; } // Deactivate profile const { error: profileError } = await supabaseClient .from('profiles') .update({ deactivated: true, deactivated_at: new Date().toISOString(), deactivation_reason: 'User requested account deletion', }) .eq('user_id', user.id); if (profileError) { throw profileError; } // Send confirmation email const emailPayload = { to: user.email, subject: 'Account Deletion Requested - Confirmation Code Inside', html: `
Hello,
We received a request to delete your account on ${new Date().toLocaleDateString()}.
Your account has been deactivated and will be permanently deleted on ${scheduledDeletionAt.toLocaleDateString()} (14 days from now).
To confirm deletion after the 14-day period, you'll need to enter this 6-digit code.
Need to cancel? Log in and visit your account settings to reactivate your account at any time during the next 14 days.
`, }; // Send via ForwardEmail API const forwardEmailKey = Deno.env.get('FORWARDEMAIL_API_KEY'); const fromEmail = Deno.env.get('FROM_EMAIL_ADDRESS') || 'noreply@thrillwiki.com'; if (forwardEmailKey) { try { await fetch('https://api.forwardemail.net/v1/emails', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Basic ${btoa(forwardEmailKey + ':')}`, }, body: JSON.stringify({ from: fromEmail, to: emailPayload.to, subject: emailPayload.subject, html: emailPayload.html, }), }); console.log('Deletion confirmation email sent'); } catch (emailError) { console.error('Failed to send email:', emailError); } } return new Response( JSON.stringify({ success: true, message: 'Account deletion request created successfully', scheduled_deletion_at: scheduledDeletionAt.toISOString(), request_id: deletionRequest.id, }), { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' }, } ); } catch (error) { console.error('Error processing deletion request:', error); return new Response( JSON.stringify({ error: error.message }), { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' }, } ); } });