-- ===================================================== -- 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 ALL existing policies first to avoid conflicts DROP POLICY IF EXISTS "Authenticated users can upload brand assets" ON storage.objects; DROP POLICY IF EXISTS "Authenticated users can update 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; DROP POLICY IF EXISTS "Authenticated users can list 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/%') ); -- Policy 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 FROM pg_policies WHERE tablename = 'objects' AND schemaname = 'storage' AND policyname LIKE '%brand assets%'; -- 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';