mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 06:11:11 -05:00
Refactor security policies
This commit is contained in:
@@ -19,25 +19,26 @@ export function LocationDisplay({ location, userId, isOwnProfile }: LocationDisp
|
||||
}, [userId, isOwnProfile]);
|
||||
|
||||
const fetchLocationPrivacy = async () => {
|
||||
// Always show location for own profile
|
||||
if (isOwnProfile) {
|
||||
setShowLocation(true);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { data } = await supabase
|
||||
.from('user_preferences')
|
||||
.select('privacy_settings')
|
||||
.eq('user_id', userId)
|
||||
.maybeSingle();
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
const viewerId = user?.id;
|
||||
|
||||
if (data?.privacy_settings) {
|
||||
const settings = data.privacy_settings as any;
|
||||
setShowLocation(settings.show_location || false);
|
||||
// Use the secure function to check location visibility
|
||||
const { data, error } = await supabase
|
||||
.rpc('can_view_user_location', {
|
||||
_viewer_id: viewerId,
|
||||
_profile_user_id: userId
|
||||
});
|
||||
|
||||
if (error) {
|
||||
console.error('Error checking location privacy:', error);
|
||||
setShowLocation(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setShowLocation(data || false);
|
||||
} catch (error) {
|
||||
console.error('Error fetching location privacy:', error);
|
||||
console.error('Error checking location privacy:', error);
|
||||
setShowLocation(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -16,23 +16,24 @@ export function PersonalLocationDisplay({ personalLocation, userId, isOwnProfile
|
||||
}, [userId, isOwnProfile]);
|
||||
|
||||
const fetchLocationPrivacy = async () => {
|
||||
// Always show location for own profile
|
||||
if (isOwnProfile) {
|
||||
setShowLocation(true);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { data } = await supabase
|
||||
.from('user_preferences')
|
||||
.select('privacy_settings')
|
||||
.eq('user_id', userId)
|
||||
.maybeSingle();
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
const viewerId = user?.id;
|
||||
|
||||
if (data?.privacy_settings) {
|
||||
const settings = data.privacy_settings as any;
|
||||
setShowLocation(settings.show_location || false);
|
||||
// Use the secure function to check location visibility
|
||||
const { data, error } = await supabase
|
||||
.rpc('can_view_user_location', {
|
||||
_viewer_id: viewerId,
|
||||
_profile_user_id: userId
|
||||
});
|
||||
|
||||
if (error) {
|
||||
console.error('Error checking location privacy:', error);
|
||||
setShowLocation(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setShowLocation(data || false);
|
||||
} catch (error) {
|
||||
console.error('Error fetching location privacy:', error);
|
||||
setShowLocation(false);
|
||||
|
||||
@@ -964,6 +964,10 @@ export type Database = {
|
||||
}
|
||||
Returns: boolean
|
||||
}
|
||||
can_view_user_location: {
|
||||
Args: { _profile_user_id: string; _viewer_id: string }
|
||||
Returns: boolean
|
||||
}
|
||||
get_user_management_permissions: {
|
||||
Args: { _user_id: string }
|
||||
Returns: Json
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
-- Fix user_preferences privacy exposure
|
||||
-- Drop the overly permissive policy
|
||||
DROP POLICY IF EXISTS "Allow reading privacy settings for permission checks" ON public.user_preferences;
|
||||
|
||||
-- Create a restricted policy: users can only read their own preferences
|
||||
CREATE POLICY "Users can read their own preferences"
|
||||
ON public.user_preferences
|
||||
FOR SELECT
|
||||
TO authenticated
|
||||
USING (auth.uid() = user_id);
|
||||
|
||||
-- Create a policy for moderators to read all preferences
|
||||
CREATE POLICY "Moderators can read all preferences"
|
||||
ON public.user_preferences
|
||||
FOR SELECT
|
||||
TO authenticated
|
||||
USING (is_moderator(auth.uid()));
|
||||
|
||||
-- Create a security definer function to check if a user's location should be visible
|
||||
CREATE OR REPLACE FUNCTION public.can_view_user_location(_viewer_id uuid, _profile_user_id uuid)
|
||||
RETURNS boolean
|
||||
LANGUAGE plpgsql
|
||||
STABLE
|
||||
SECURITY DEFINER
|
||||
SET search_path = public
|
||||
AS $$
|
||||
DECLARE
|
||||
user_privacy_settings jsonb;
|
||||
BEGIN
|
||||
-- Always allow users to view their own location
|
||||
IF _viewer_id = _profile_user_id THEN
|
||||
RETURN true;
|
||||
END IF;
|
||||
|
||||
-- Allow moderators to view all locations
|
||||
IF is_moderator(_viewer_id) THEN
|
||||
RETURN true;
|
||||
END IF;
|
||||
|
||||
-- Check the user's privacy settings
|
||||
SELECT privacy_settings INTO user_privacy_settings
|
||||
FROM public.user_preferences
|
||||
WHERE user_id = _profile_user_id;
|
||||
|
||||
-- If no privacy settings found, default to not showing location
|
||||
IF user_privacy_settings IS NULL THEN
|
||||
RETURN false;
|
||||
END IF;
|
||||
|
||||
-- Check if the user has enabled location visibility
|
||||
RETURN COALESCE((user_privacy_settings->>'show_location')::boolean, false);
|
||||
END;
|
||||
$$;
|
||||
Reference in New Issue
Block a user