mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 08:11:13 -05:00
168 lines
5.4 KiB
TypeScript
168 lines
5.4 KiB
TypeScript
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;
|
|
}
|
|
|
|
// Send confirmation email
|
|
const emailPayload = {
|
|
to: user.email,
|
|
subject: 'Account Deletion Requested - Confirmation Code Inside',
|
|
html: `
|
|
<h2>Account Deletion Requested</h2>
|
|
<p>Hello,</p>
|
|
<p>We received a request to delete your account on ${new Date().toLocaleDateString()}.</p>
|
|
|
|
<h3>IMPORTANT INFORMATION:</h3>
|
|
<p>You must enter the confirmation code within 24 hours. Once confirmed, your account will be deactivated and permanently deleted on <strong>${scheduledDeletionAt.toLocaleDateString()}</strong> (14 days from confirmation).</p>
|
|
|
|
<h4>What will be DELETED:</h4>
|
|
<ul>
|
|
<li>✗ Your profile information (username, bio, avatar, etc.)</li>
|
|
<li>✗ Your reviews and ratings</li>
|
|
<li>✗ Your personal preferences and settings</li>
|
|
</ul>
|
|
|
|
<h4>What will be PRESERVED:</h4>
|
|
<ul>
|
|
<li>✓ Your database submissions (park creations, ride additions, edits)</li>
|
|
<li>✓ Photos you've uploaded (will be shown as "Submitted by [deleted user]")</li>
|
|
<li>✓ Edit history and contributions</li>
|
|
</ul>
|
|
|
|
<h3>CONFIRMATION CODE: <strong>${confirmationCode}</strong></h3>
|
|
<p><strong>IMPORTANT:</strong> You have 24 hours to enter this code to confirm the deletion. After entering the code, your account will be deactivated and you'll have 14 days to cancel before permanent deletion.</p>
|
|
|
|
<p><strong>Need to cancel?</strong> You can cancel at any time during the 14-day period after confirming.</p>
|
|
`,
|
|
};
|
|
|
|
// 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' },
|
|
}
|
|
);
|
|
}
|
|
});
|