mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-24 07:51:12 -05:00
Fix profile privacy and simplify code
This commit is contained in:
@@ -10,25 +10,47 @@ export function useProfile(userId: string | undefined) {
|
||||
queryFn: async () => {
|
||||
if (!userId) return null;
|
||||
|
||||
console.log('[useProfile] Fetching profile for userId:', userId);
|
||||
console.log('[useProfile] Fetching filtered profile for userId:', userId);
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('profiles')
|
||||
.select('*, location:locations(*)')
|
||||
.eq('user_id', userId)
|
||||
.maybeSingle();
|
||||
// Get current viewer ID
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
const viewerId = user?.id || null;
|
||||
|
||||
// Use get_filtered_profile RPC for privacy-aware field filtering
|
||||
const { data, error } = await supabase.rpc('get_filtered_profile', {
|
||||
_profile_user_id: userId,
|
||||
_viewer_id: viewerId
|
||||
});
|
||||
|
||||
if (error) {
|
||||
console.error('[useProfile] Error:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
console.log('[useProfile] Profile loaded:', {
|
||||
username: data?.username,
|
||||
avatar_url: data?.avatar_url
|
||||
if (!data) return null;
|
||||
|
||||
// Type assertion since we know the structure from the RPC function
|
||||
const profileData = data as unknown as Profile;
|
||||
|
||||
// Fetch location separately if location_id is present and visible
|
||||
if (profileData.location_id) {
|
||||
const { data: location } = await supabase
|
||||
.from('locations')
|
||||
.select('*')
|
||||
.eq('id', profileData.location_id)
|
||||
.single();
|
||||
|
||||
if (location) {
|
||||
profileData.location = location;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[useProfile] Filtered profile loaded:', {
|
||||
username: profileData.username,
|
||||
has_avatar: !!profileData.avatar_url
|
||||
});
|
||||
|
||||
return data as Profile;
|
||||
return profileData;
|
||||
},
|
||||
enabled: !!userId,
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { useAuth } from '@/hooks/useAuth';
|
||||
|
||||
interface ProfileFieldAccess {
|
||||
[fieldName: string]: boolean;
|
||||
}
|
||||
|
||||
export function useProfileFieldAccess(profileUserId: string | null | undefined) {
|
||||
const { user } = useAuth();
|
||||
const [fieldAccess, setFieldAccess] = useState<ProfileFieldAccess>({});
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (!profileUserId) {
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
checkFieldAccess();
|
||||
}, [profileUserId, user?.id]);
|
||||
|
||||
const checkFieldAccess = async () => {
|
||||
if (!profileUserId || !user?.id) {
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
// Fields that might need privacy checking
|
||||
const fieldsToCheck = [
|
||||
'date_of_birth',
|
||||
'personal_location',
|
||||
'location_id',
|
||||
'preferred_pronouns',
|
||||
'home_park_id',
|
||||
'bio',
|
||||
'avatar_url',
|
||||
'avatar_image_id'
|
||||
];
|
||||
|
||||
const accessChecks: ProfileFieldAccess = {};
|
||||
|
||||
// Check each field individually using our security definer function
|
||||
for (const field of fieldsToCheck) {
|
||||
const { data, error } = await supabase.rpc('can_view_profile_field', {
|
||||
_viewer_id: user.id,
|
||||
_profile_user_id: profileUserId,
|
||||
_field_name: field
|
||||
});
|
||||
|
||||
if (error) {
|
||||
console.error(`Error checking access for field ${field}:`, error);
|
||||
accessChecks[field] = false;
|
||||
} else {
|
||||
accessChecks[field] = data === true;
|
||||
}
|
||||
}
|
||||
|
||||
setFieldAccess(accessChecks);
|
||||
} catch (error) {
|
||||
console.error('Error checking field access:', error);
|
||||
// Default to denying access on error
|
||||
setFieldAccess({});
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const canViewField = (fieldName: string): boolean => {
|
||||
if (!profileUserId || !user?.id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Users can always see their own fields
|
||||
if (user.id === profileUserId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return fieldAccess[fieldName] || false;
|
||||
};
|
||||
|
||||
const refresh = () => {
|
||||
checkFieldAccess();
|
||||
};
|
||||
|
||||
return {
|
||||
canViewField,
|
||||
loading,
|
||||
refresh
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user