Files
alva/supabase/migrations/20260711140036_677fb7f4-3e2b-4614-ba6b-5fe5b28ff48b.sql
T
gpt-engineer-app[bot] 1920495d9b Changes
Co-authored-by: wolfoftyreso-debug <250630591+wolfoftyreso-debug@users.noreply.github.com>
2026-07-11 14:00:38 +00:00

29 lines
1.1 KiB
PL/PgSQL

-- Restrict direct execution of SECURITY DEFINER function has_role.
-- Switching to SECURITY INVOKER: when called as auth.uid() the user_roles
-- RLS policy already lets a user see (only) their own role rows, so
-- has_role(auth.uid(), 'admin') still returns correctly.
-- We also revoke EXECUTE from anon/public so the function cannot be
-- invoked directly from the Data API.
CREATE OR REPLACE FUNCTION public.has_role(_user_id uuid, _role app_role)
RETURNS boolean
LANGUAGE sql
STABLE
SECURITY INVOKER
SET search_path = public
AS $$
SELECT EXISTS (
SELECT 1
FROM public.user_roles
WHERE user_id = _user_id
AND role = _role
)
$$;
REVOKE EXECUTE ON FUNCTION public.has_role(uuid, app_role) FROM PUBLIC;
REVOKE EXECUTE ON FUNCTION public.has_role(uuid, app_role) FROM anon;
-- authenticated retains EXECUTE so RLS policies referencing has_role
-- continue to work; the function itself is now SECURITY INVOKER so it
-- cannot be used to bypass RLS.
GRANT EXECUTE ON FUNCTION public.has_role(uuid, app_role) TO authenticated;
GRANT EXECUTE ON FUNCTION public.has_role(uuid, app_role) TO service_role;