-- ===================================================== -- STORAGE RLS POLICIES FOR LOGO/FAVICON UPLOAD -- ===================================================== -- This fixes the "new row violates row-level security policy" error -- when uploading logo/favicon to Supabase Storage -- ===================================================== -- Step 1: Verify the 'content' bucket exists SELECT * FROM storage.buckets WHERE name = 'content'; -- If no rows returned, create the bucket: -- INSERT INTO storage.buckets (id, name, public) -- VALUES ('content', 'content', true); -- Step 2: Drop existing policies (if any) on brand-assets DROP POLICY IF EXISTS "Authenticated users can upload brand assets" ON storage.objects; DROP POLICY IF EXISTS "Authenticated users can delete brand assets" ON storage.objects; DROP POLICY IF EXISTS "Public can view brand assets" ON storage.objects; -- Step 3: Create policies for brand-assets upload -- Policy 1: Allow authenticated users to INSERT (upload) files to brand-assets folder CREATE POLICY "Authenticated users can upload brand assets" ON storage.objects FOR INSERT TO authenticated WITH CHECK ( bucket_id = 'content' AND (name LIKE 'brand-assets/logo/%' OR name LIKE 'brand-assets/favicon/%') ); -- Policy 2: Allow authenticated users to UPDATE (replace) files in brand-assets folder CREATE POLICY "Authenticated users can update brand assets" ON storage.objects FOR UPDATE TO authenticated USING ( bucket_id = 'content' AND (name LIKE 'brand-assets/logo/%' OR name LIKE 'brand-assets/favicon/%') ) WITH CHECK ( bucket_id = 'content' AND (name LIKE 'brand-assets/logo/%' OR name LIKE 'brand-assets/favicon/%') ); -- Policy 3: Allow authenticated users to DELETE files in brand-assets folder CREATE POLICY "Authenticated users can delete brand assets" ON storage.objects FOR DELETE TO authenticated USING ( bucket_id = 'content' AND (name LIKE 'brand-assets/logo/%' OR name LIKE 'brand-assets/favicon/%') ); -- Policy 4: Allow public SELECT (view) on brand-assets (for displaying images) CREATE POLICY "Public can view brand assets" ON storage.objects FOR SELECT TO public USING ( bucket_id = 'content' AND (name LIKE 'brand-assets/logo/%' OR name LIKE 'brand-assets/favicon/%') ); -- Step 5: Allow LIST operation for authenticated users (needed for auto-delete) CREATE POLICY "Authenticated users can list brand assets" ON storage.objects FOR SELECT TO authenticated USING ( bucket_id = 'content' AND (name LIKE 'brand-assets/logo%' OR name LIKE 'brand-assets/favicon%') ); -- ===================================================== -- VERIFICATION QUERIES -- ===================================================== -- Check all policies on storage.objects SELECT schemaname, tablename, policyname, permissive, roles, cmd, qual, with_check FROM pg_policies WHERE tablename = 'objects' AND schemaname = 'storage'; -- Test if you can access the bucket SELECT * FROM storage.objects WHERE bucket_id = 'content' LIMIT 5; -- ===================================================== -- TROUBLESHOOTING -- ===================================================== -- If still getting RLS errors, check: -- 1. Are you logged in? SELECT auth.uid(); -- 2. Check RLS is enabled SELECT tablename, rowsecurity FROM pg_tables WHERE schemaname = 'storage' AND tablename = 'objects'; -- 3. Check bucket is public SELECT * FROM storage.buckets WHERE name = 'content'; -- ===================================================== -- ALTERNATIVE: Less restrictive policies (NOT RECOMMENDED for production) -- ===================================================== -- Only use these if you trust all authenticated users completely -- -- Allow full access to content bucket for authenticated users -- CREATE POLICY "Authenticated users have full access to content bucket" -- ON storage.objects FOR ALL -- TO authenticated -- USING (bucket_id = 'content') -- WITH CHECK (bucket_id = 'content');