feat: Implement comprehensive ban enforcement

This commit is contained in:
gpt-engineer-app[bot]
2025-10-30 01:47:51 +00:00
parent f95eaf9eb7
commit fe76c8c572
8 changed files with 452 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
import { createClient, SupabaseClient } from "https://esm.sh/@supabase/supabase-js@2.57.4";
import { edgeLogger } from "./logger.ts";
export async function checkUserBanned(
userId: string,
supabase: SupabaseClient
): Promise<{ banned: boolean; error?: string }> {
try {
const { data: profile, error } = await supabase
.from('profiles')
.select('banned')
.eq('user_id', userId)
.single();
if (error) {
edgeLogger.error('Ban check failed', { userId, error: error.message });
return { banned: false, error: 'Unable to verify account status' };
}
if (!profile) {
return { banned: false, error: 'Profile not found' };
}
return { banned: profile.banned };
} catch (error) {
edgeLogger.error('Ban check exception', { userId, error });
return { banned: false, error: 'Internal error checking account status' };
}
}
export function createBannedResponse(requestId: string, corsHeaders: Record<string, string>) {
return new Response(
JSON.stringify({
error: 'Account suspended',
message: 'Your account has been suspended. Contact support for assistance.',
requestId
}),
{
status: 403,
headers: {
...corsHeaders,
'Content-Type': 'application/json',
'X-Request-ID': requestId
}
}
);
}

View File

@@ -116,6 +116,60 @@ serve(async (req) => {
edgeLogger.info('Authentication successful', { action: 'approval_auth_success', userId: user.id });
// Check if user is banned
const { data: profile, error: profileError } = await supabaseAuth
.from('profiles')
.select('banned')
.eq('user_id', user.id)
.single();
if (profileError || !profile) {
edgeLogger.error('Profile check failed', {
action: 'approval_profile_check',
error: profileError?.message,
requestId: tracking.requestId
});
const duration = endRequest(tracking);
return new Response(
JSON.stringify({
error: 'Unable to verify user profile',
requestId: tracking.requestId
}),
{
status: 403,
headers: {
...corsHeaders,
'Content-Type': 'application/json',
'X-Request-ID': tracking.requestId
}
}
);
}
if (profile.banned) {
edgeLogger.warn('Banned user attempted approval', {
action: 'approval_banned_user',
userId: user.id,
requestId: tracking.requestId
});
const duration = endRequest(tracking);
return new Response(
JSON.stringify({
error: 'Account suspended',
message: 'Your account has been suspended. Contact support for assistance.',
requestId: tracking.requestId
}),
{
status: 403,
headers: {
...corsHeaders,
'Content-Type': 'application/json',
'X-Request-ID': tracking.requestId
}
}
);
}
// SECURITY NOTE: Service role key used later in this function
// Reason: Need to bypass RLS to write approved changes to entity tables
// (parks, rides, companies, ride_models) which have RLS policies