From 5cd78854e39f050f79ebe0c8d4087cef047d379f Mon Sep 17 00:00:00 2001 From: DanielS Date: Thu, 9 Jul 2026 23:15:16 +0200 Subject: [PATCH] db: fix infinite RLS recursion on users table causing admin lockout --- ...20260709231500_fix_users_rls_recursion.sql | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 shop/supabase/migrations/20260709231500_fix_users_rls_recursion.sql diff --git a/shop/supabase/migrations/20260709231500_fix_users_rls_recursion.sql b/shop/supabase/migrations/20260709231500_fix_users_rls_recursion.sql new file mode 100644 index 0000000..715c98b --- /dev/null +++ b/shop/supabase/migrations/20260709231500_fix_users_rls_recursion.sql @@ -0,0 +1,22 @@ +-- Migration: Fix Users RLS Recursion and Admin Lockout +-- Purpose: Implement a security definer function to check admin status, avoiding infinite recursion on public.users. + +-- 1. Create helper function to check admin role bypassing RLS (SECURITY DEFINER) +CREATE OR REPLACE FUNCTION public.is_admin(user_id UUID) +RETURNS BOOLEAN AS $$ +BEGIN + RETURN EXISTS ( + SELECT 1 FROM public.users + WHERE id = user_id AND role = 'admin' + ); +END; +$$ LANGUAGE plpgsql SECURITY DEFINER; + +-- 2. Drop the recursive policy on public.users +DROP POLICY IF EXISTS select_all_users_for_admin ON public.users; + +-- 3. Re-create the policy using the non-recursive helper function +CREATE POLICY select_all_users_for_admin ON public.users + FOR SELECT + TO authenticated + USING (public.is_admin(auth.uid()));