diff --git a/supabase/functions/upload-image/index.ts b/supabase/functions/upload-image/index.ts index 0232ba9c..c2a2c700 100644 --- a/supabase/functions/upload-image/index.ts +++ b/supabase/functions/upload-image/index.ts @@ -70,6 +70,36 @@ const createAuthenticatedSupabaseClient = (authHeader: string) => { }) } +/** + * Report ban evasion attempts to system alerts + */ +async function reportBanEvasionToAlerts( + supabaseClient: any, + userId: string, + action: string, + requestId: string +): Promise { + try { + await supabaseClient.rpc('create_system_alert', { + p_alert_type: 'ban_attempt', + p_severity: 'high', + p_message: `Banned user attempted image upload: ${action}`, + p_metadata: { + user_id: userId, + action, + request_id: requestId, + timestamp: new Date().toISOString() + } + }); + } catch (error) { + // Non-blocking - log but don't fail the response + edgeLogger.warn('Failed to report ban evasion', { + error: error instanceof Error ? error.message : String(error), + requestId + }); + } +} + // Apply strict rate limiting (5 requests/minute) to prevent abuse const uploadRateLimiter = rateLimiters.strict; @@ -164,7 +194,15 @@ serve(withRateLimit(async (req) => { } if (profile.banned) { + // Report ban evasion attempt (non-blocking) + await reportBanEvasionToAlerts(supabase, user.id, 'image_delete', tracking.requestId); + const duration = endRequest(tracking); + edgeLogger.warn('Banned user blocked from image deletion', { + userId: user.id, + requestId: tracking.requestId + }); + return new Response( JSON.stringify({ error: 'Account suspended', @@ -375,7 +413,15 @@ serve(withRateLimit(async (req) => { } if (profile.banned) { + // Report ban evasion attempt (non-blocking) + await reportBanEvasionToAlerts(supabase, user.id, 'image_upload', tracking.requestId); + const duration = endRequest(tracking); + edgeLogger.warn('Banned user blocked from image upload', { + userId: user.id, + requestId: tracking.requestId + }); + return new Response( JSON.stringify({ error: 'Account suspended',