mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 15:51:12 -05:00
122 lines
3.5 KiB
TypeScript
122 lines
3.5 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.39.3';
|
|
import { edgeLogger } from "../_shared/logger.ts";
|
|
|
|
const corsHeaders = {
|
|
'Access-Control-Allow-Origin': '*',
|
|
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
|
|
};
|
|
|
|
// Simple request tracking
|
|
const startRequest = () => ({ requestId: crypto.randomUUID(), start: Date.now() });
|
|
const endRequest = (tracking: { start: number }) => Date.now() - tracking.start;
|
|
|
|
// Common disposable email domains (subset for performance)
|
|
const DISPOSABLE_DOMAINS = new Set([
|
|
'tempmail.com', 'guerrillamail.com', '10minutemail.com', 'mailinator.com',
|
|
'throwaway.email', 'temp-mail.org', 'fakeinbox.com', 'maildrop.cc',
|
|
'yopmail.com', 'sharklasers.com', 'guerrillamailblock.com'
|
|
]);
|
|
|
|
interface EmailValidationResult {
|
|
valid: boolean;
|
|
reason?: string;
|
|
suggestions?: string[];
|
|
}
|
|
|
|
function validateEmailFormat(email: string): EmailValidationResult {
|
|
// Basic format validation
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
if (!emailRegex.test(email)) {
|
|
return { valid: false, reason: 'Invalid email format' };
|
|
}
|
|
|
|
// Extract domain
|
|
const domain = email.split('@')[1].toLowerCase();
|
|
|
|
// Check against disposable domains
|
|
if (DISPOSABLE_DOMAINS.has(domain)) {
|
|
return {
|
|
valid: false,
|
|
reason: 'Disposable email addresses are not allowed. Please use a permanent email address.',
|
|
suggestions: ['gmail.com', 'outlook.com', 'yahoo.com', 'protonmail.com']
|
|
};
|
|
}
|
|
|
|
// Check for suspicious patterns
|
|
if (domain.includes('temp') || domain.includes('disposable') || domain.includes('trash')) {
|
|
return {
|
|
valid: false,
|
|
reason: 'This email domain appears to be temporary. Please use a permanent email address.',
|
|
};
|
|
}
|
|
|
|
return { valid: true };
|
|
}
|
|
|
|
serve(async (req) => {
|
|
const tracking = startRequest();
|
|
|
|
// Handle CORS preflight requests
|
|
if (req.method === 'OPTIONS') {
|
|
return new Response(null, { headers: corsHeaders });
|
|
}
|
|
|
|
try {
|
|
const { email } = await req.json();
|
|
|
|
if (!email || typeof email !== 'string') {
|
|
return new Response(
|
|
JSON.stringify({ valid: false, reason: 'Email is required', requestId: tracking.requestId }),
|
|
{
|
|
status: 400,
|
|
headers: {
|
|
...corsHeaders,
|
|
'Content-Type': 'application/json',
|
|
'X-Request-ID': tracking.requestId
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
// Validate email
|
|
const result = validateEmailFormat(email.toLowerCase().trim());
|
|
const duration = endRequest(tracking);
|
|
|
|
return new Response(
|
|
JSON.stringify({ ...result, requestId: tracking.requestId }),
|
|
{
|
|
status: 200,
|
|
headers: {
|
|
...corsHeaders,
|
|
'Content-Type': 'application/json',
|
|
'X-Request-ID': tracking.requestId
|
|
}
|
|
}
|
|
);
|
|
} catch (error) {
|
|
const duration = endRequest(tracking);
|
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
edgeLogger.error('Email validation error', {
|
|
error: errorMessage,
|
|
requestId: tracking.requestId,
|
|
duration
|
|
});
|
|
return new Response(
|
|
JSON.stringify({
|
|
valid: false,
|
|
reason: 'Failed to validate email. Please try again.',
|
|
requestId: tracking.requestId
|
|
}),
|
|
{
|
|
status: 500,
|
|
headers: {
|
|
...corsHeaders,
|
|
'Content-Type': 'application/json',
|
|
'X-Request-ID': tracking.requestId
|
|
}
|
|
}
|
|
);
|
|
}
|
|
});
|