-- Optimize RLS policies to prevent auth.uid() re-evaluation per row -- This migration drops and recreates all affected policies with optimized syntax -- Pattern: auth.uid() → (SELECT auth.uid()) -- Pattern: is_moderator(auth.uid()) → is_moderator((SELECT auth.uid())) -- ============================================================================ -- CONTACT EMAIL THREADS -- ============================================================================ DROP POLICY IF EXISTS "Admin staff can insert email threads" ON public.contact_email_threads; DROP POLICY IF EXISTS "Admin staff can view all email threads" ON public.contact_email_threads; CREATE POLICY "Admin staff can insert email threads" ON public.contact_email_threads FOR INSERT TO authenticated WITH CHECK ( has_role((SELECT auth.uid()), 'superuser'::app_role) OR has_role((SELECT auth.uid()), 'admin'::app_role) OR has_role((SELECT auth.uid()), 'moderator'::app_role) ); CREATE POLICY "Admin staff can view all email threads" ON public.contact_email_threads FOR SELECT TO authenticated USING ( has_role((SELECT auth.uid()), 'superuser'::app_role) OR has_role((SELECT auth.uid()), 'admin'::app_role) OR has_role((SELECT auth.uid()), 'moderator'::app_role) ); -- ============================================================================ -- PROFILES -- ============================================================================ DROP POLICY IF EXISTS "Admins and moderators can view all profiles" ON public.profiles; DROP POLICY IF EXISTS "Admins can update any profile with MFA" ON public.profiles; CREATE POLICY "Admins and moderators can view all profiles" ON public.profiles FOR SELECT TO authenticated USING (is_moderator((SELECT auth.uid()))); CREATE POLICY "Admins can update any profile with MFA" ON public.profiles FOR UPDATE TO authenticated USING (is_moderator((SELECT auth.uid())) AND has_aal2()); -- ============================================================================ -- BLOG POSTS -- ============================================================================ DROP POLICY IF EXISTS "Admins and superusers can manage blog posts" ON public.blog_posts; CREATE POLICY "Admins and superusers can manage blog posts" ON public.blog_posts FOR ALL TO authenticated USING ( (has_role((SELECT auth.uid()), 'admin'::app_role) OR has_role((SELECT auth.uid()), 'superuser'::app_role)) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- USER ROLES -- ============================================================================ DROP POLICY IF EXISTS "Admins can delete user roles with MFA" ON public.user_roles; DROP POLICY IF EXISTS "Admins can insert user roles with MFA" ON public.user_roles; DROP POLICY IF EXISTS "Admins can manage all user roles" ON public.user_roles; DROP POLICY IF EXISTS "Moderators can manage roles" ON public.user_roles; CREATE POLICY "Admins can delete user roles with MFA" ON public.user_roles FOR DELETE TO authenticated USING (is_moderator((SELECT auth.uid())) AND has_aal2()); CREATE POLICY "Admins can insert user roles with MFA" ON public.user_roles FOR INSERT TO authenticated WITH CHECK (is_moderator((SELECT auth.uid())) AND has_aal2()); CREATE POLICY "Admins can manage all user roles" ON public.user_roles FOR SELECT TO authenticated USING (is_moderator((SELECT auth.uid()))); CREATE POLICY "Moderators can manage roles" ON public.user_roles FOR UPDATE TO authenticated USING (is_moderator((SELECT auth.uid()))); -- ============================================================================ -- ADMIN AUDIT LOG -- ============================================================================ DROP POLICY IF EXISTS "Admins can insert audit log with MFA" ON public.admin_audit_log; DROP POLICY IF EXISTS "Admins can view audit log" ON public.admin_audit_log; CREATE POLICY "Admins can insert audit log with MFA" ON public.admin_audit_log FOR INSERT TO authenticated WITH CHECK (is_moderator((SELECT auth.uid())) AND has_aal2()); CREATE POLICY "Admins can view audit log" ON public.admin_audit_log FOR SELECT TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- NOTIFICATION CHANNELS -- ============================================================================ DROP POLICY IF EXISTS "Admins can manage notification channels" ON public.notification_channels; CREATE POLICY "Admins can manage notification channels" ON public.notification_channels FOR ALL TO authenticated USING (is_moderator((SELECT auth.uid()))); -- ============================================================================ -- NOTIFICATION TEMPLATES -- ============================================================================ DROP POLICY IF EXISTS "Admins can manage notification templates" ON public.notification_templates; CREATE POLICY "Admins can manage notification templates" ON public.notification_templates FOR ALL TO authenticated USING (is_moderator((SELECT auth.uid()))); -- ============================================================================ -- ACCOUNT DELETION REQUESTS -- ============================================================================ DROP POLICY IF EXISTS "Admins can view all deletion requests" ON public.account_deletion_requests; CREATE POLICY "Admins can view all deletion requests" ON public.account_deletion_requests FOR SELECT TO authenticated USING (is_moderator((SELECT auth.uid()))); -- ============================================================================ -- COMPANY SUBMISSIONS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can delete company submissions" ON public.company_submissions; DROP POLICY IF EXISTS "Moderators can update company submissions" ON public.company_submissions; DROP POLICY IF EXISTS "Moderators can view all company submissions" ON public.company_submissions; CREATE POLICY "Moderators can delete company submissions" ON public.company_submissions FOR DELETE TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); CREATE POLICY "Moderators can update company submissions" ON public.company_submissions FOR UPDATE TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); CREATE POLICY "Moderators can view all company submissions" ON public.company_submissions FOR SELECT TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- CONTACT SUBMISSIONS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can delete contact submissions" ON public.contact_submissions; DROP POLICY IF EXISTS "Moderators can update contact submissions" ON public.contact_submissions; DROP POLICY IF EXISTS "Moderators can view all contact submissions" ON public.contact_submissions; CREATE POLICY "Moderators can delete contact submissions" ON public.contact_submissions FOR DELETE TO authenticated USING (is_moderator((SELECT auth.uid())) AND has_aal2()); CREATE POLICY "Moderators can update contact submissions" ON public.contact_submissions FOR UPDATE TO authenticated USING (is_moderator((SELECT auth.uid())) AND ((NOT has_mfa_enabled((SELECT auth.uid()))) OR has_aal2())) WITH CHECK (is_moderator((SELECT auth.uid())) AND ((NOT has_mfa_enabled((SELECT auth.uid()))) OR has_aal2())); CREATE POLICY "Moderators can view all contact submissions" ON public.contact_submissions FOR SELECT TO authenticated USING (is_moderator((SELECT auth.uid()))); -- ============================================================================ -- PARK SUBMISSIONS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can delete park submissions" ON public.park_submissions; DROP POLICY IF EXISTS "Moderators can update park submissions" ON public.park_submissions; DROP POLICY IF EXISTS "Moderators can view all park submissions" ON public.park_submissions; CREATE POLICY "Moderators can delete park submissions" ON public.park_submissions FOR DELETE TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); CREATE POLICY "Moderators can update park submissions" ON public.park_submissions FOR UPDATE TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); CREATE POLICY "Moderators can view all park submissions" ON public.park_submissions FOR SELECT TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- ENTITY TIMELINE EVENTS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can delete timeline events" ON public.entity_timeline_events; DROP POLICY IF EXISTS "Moderators can update timeline events" ON public.entity_timeline_events; DROP POLICY IF EXISTS "Moderators can view all timeline events" ON public.entity_timeline_events; CREATE POLICY "Moderators can delete timeline events" ON public.entity_timeline_events FOR DELETE TO authenticated USING (is_moderator((SELECT auth.uid())) AND has_aal2()); CREATE POLICY "Moderators can update timeline events" ON public.entity_timeline_events FOR UPDATE TO authenticated USING (is_moderator((SELECT auth.uid())) AND has_aal2()) WITH CHECK (is_moderator((SELECT auth.uid())) AND has_aal2()); CREATE POLICY "Moderators can view all timeline events" ON public.entity_timeline_events FOR SELECT TO authenticated USING (is_moderator((SELECT auth.uid())) AND has_aal2()); -- ============================================================================ -- PHOTO SUBMISSION ITEMS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can delete photo submission items" ON public.photo_submission_items; CREATE POLICY "Moderators can delete photo submission items" ON public.photo_submission_items FOR DELETE TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- PHOTO SUBMISSIONS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can delete photo submissions" ON public.photo_submissions; CREATE POLICY "Moderators can delete photo submissions" ON public.photo_submissions FOR DELETE TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- REPORTS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can delete reports" ON public.reports; CREATE POLICY "Moderators can delete reports" ON public.reports FOR DELETE TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- RIDE MODEL SUBMISSIONS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can delete ride model submissions" ON public.ride_model_submissions; CREATE POLICY "Moderators can delete ride model submissions" ON public.ride_model_submissions FOR DELETE TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- RIDE SUBMISSIONS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can delete ride submissions" ON public.ride_submissions; CREATE POLICY "Moderators can delete ride submissions" ON public.ride_submissions FOR DELETE TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- SUBMISSION ITEMS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can delete submission items" ON public.submission_items; DROP POLICY IF EXISTS "Moderators can insert submission items" ON public.submission_items; CREATE POLICY "Moderators can delete submission items" ON public.submission_items FOR DELETE TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); CREATE POLICY "Moderators can insert submission items" ON public.submission_items FOR INSERT TO authenticated WITH CHECK ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- CONTENT SUBMISSIONS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can delete submissions with MFA" ON public.content_submissions; DROP POLICY IF EXISTS "Moderators can update submissions" ON public.content_submissions; DROP POLICY IF EXISTS "Moderators can view all submissions" ON public.content_submissions; CREATE POLICY "Moderators can delete submissions with MFA" ON public.content_submissions FOR DELETE TO authenticated USING (is_moderator((SELECT auth.uid())) AND has_aal2()); CREATE POLICY "Moderators can update submissions" ON public.content_submissions FOR UPDATE TO authenticated USING (is_moderator((SELECT auth.uid())) AND ((NOT has_mfa_enabled((SELECT auth.uid()))) OR has_aal2())) WITH CHECK (is_moderator((SELECT auth.uid())) AND ((NOT has_mfa_enabled((SELECT auth.uid()))) OR has_aal2())); CREATE POLICY "Moderators can view all submissions" ON public.content_submissions FOR SELECT TO authenticated USING (is_moderator((SELECT auth.uid())) AND ((NOT has_mfa_enabled((SELECT auth.uid()))) OR has_aal2())); -- ============================================================================ -- TIMELINE EVENT SUBMISSIONS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can delete timeline submissions" ON public.timeline_event_submissions; CREATE POLICY "Moderators can delete timeline submissions" ON public.timeline_event_submissions FOR DELETE TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- LOCATIONS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can insert locations" ON public.locations; DROP POLICY IF EXISTS "Moderators can update locations" ON public.locations; CREATE POLICY "Moderators can insert locations" ON public.locations FOR INSERT TO authenticated WITH CHECK (is_moderator((SELECT auth.uid()))); CREATE POLICY "Moderators can update locations" ON public.locations FOR UPDATE TO authenticated USING (is_moderator((SELECT auth.uid()))); -- ============================================================================ -- REVIEW PHOTOS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can manage all review photos" ON public.review_photos; CREATE POLICY "Moderators can manage all review photos" ON public.review_photos FOR ALL TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- RIDE COASTER STATS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can manage ride coaster statistics" ON public.ride_coaster_stats; CREATE POLICY "Moderators can manage ride coaster statistics" ON public.ride_coaster_stats FOR ALL TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- RIDE MODEL TECHNICAL SPECIFICATIONS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can manage ride model technical specifications" ON public.ride_model_technical_specifications; CREATE POLICY "Moderators can manage ride model technical specifications" ON public.ride_model_technical_specifications FOR ALL TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- RIDE NAME HISTORY -- ============================================================================ DROP POLICY IF EXISTS "Moderators can manage ride name history" ON public.ride_name_history; CREATE POLICY "Moderators can manage ride name history" ON public.ride_name_history FOR ALL TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- RIDE SUBMISSION COASTER STATISTICS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can manage ride submission coaster statistics" ON public.ride_submission_coaster_statistics; CREATE POLICY "Moderators can manage ride submission coaster statistics" ON public.ride_submission_coaster_statistics FOR ALL TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- RIDE SUBMISSION NAME HISTORY -- ============================================================================ DROP POLICY IF EXISTS "Moderators can manage ride submission name history" ON public.ride_submission_name_history; CREATE POLICY "Moderators can manage ride submission name history" ON public.ride_submission_name_history FOR ALL TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- RIDE SUBMISSION TECHNICAL SPECIFICATIONS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can manage ride submission technical specifications" ON public.ride_submission_technical_specifications; CREATE POLICY "Moderators can manage ride submission technical specifications" ON public.ride_submission_technical_specifications FOR ALL TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- RIDE TECHNICAL SPECIFICATIONS -- ============================================================================ DROP POLICY IF EXISTS "Moderators can manage ride technical specifications" ON public.ride_technical_specifications; CREATE POLICY "Moderators can manage ride technical specifications" ON public.ride_technical_specifications FOR ALL TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- SUBMISSION DEPENDENCIES -- ============================================================================ DROP POLICY IF EXISTS "Moderators can manage submission dependencies" ON public.submission_dependencies; CREATE POLICY "Moderators can manage submission dependencies" ON public.submission_dependencies FOR ALL TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) ); -- ============================================================================ -- TEST DATA REGISTRY -- ============================================================================ DROP POLICY IF EXISTS "Moderators can manage test data registry" ON public.test_data_registry; CREATE POLICY "Moderators can manage test data registry" ON public.test_data_registry FOR ALL TO authenticated USING ( is_moderator((SELECT auth.uid())) AND ((NOT EXISTS ( SELECT 1 FROM auth.mfa_factors WHERE mfa_factors.user_id = (SELECT auth.uid()) AND mfa_factors.status = 'verified'::auth.factor_status )) OR has_aal2()) );