Big things, maybe all's better now
This commit is contained in:
584
supabase/migrations/051_rls_performance_fixes.sql
Normal file
584
supabase/migrations/051_rls_performance_fixes.sql
Normal file
@@ -0,0 +1,584 @@
|
||||
-- ============================================================
|
||||
-- Migration 051: RLS Performance Fixes
|
||||
-- Addresses all Supabase linter warnings:
|
||||
-- 1. auth_rls_initplan: wrap auth.uid() in (select auth.uid())
|
||||
-- 2. multiple_permissive_policies: consolidate overlapping policies
|
||||
-- ============================================================
|
||||
|
||||
-- ============================================================
|
||||
-- PART 1: Fix auth_rls_initplan
|
||||
-- Replace auth.uid() with (select auth.uid()) in ALL RLS policies
|
||||
-- using a dynamic DO block that reads pg_policies catalog
|
||||
-- ============================================================
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
r record;
|
||||
qual_new text;
|
||||
check_new text;
|
||||
cmd_parts text[];
|
||||
sql_cmd text;
|
||||
BEGIN
|
||||
FOR r IN
|
||||
SELECT
|
||||
schemaname,
|
||||
tablename,
|
||||
policyname,
|
||||
permissive,
|
||||
roles,
|
||||
cmd AS policy_cmd,
|
||||
qual,
|
||||
with_check
|
||||
FROM pg_policies
|
||||
WHERE schemaname = 'public'
|
||||
AND (
|
||||
qual ~ 'auth\.uid\(\)' AND qual !~ '\(\s*select\s+auth\.uid\(\)\s*\)'
|
||||
OR
|
||||
with_check ~ 'auth\.uid\(\)' AND with_check !~ '\(\s*select\s+auth\.uid\(\)\s*\)'
|
||||
)
|
||||
LOOP
|
||||
-- Replace auth.uid() with (select auth.uid()) in USING clause
|
||||
qual_new := r.qual;
|
||||
IF qual_new IS NOT NULL THEN
|
||||
-- Avoid double-wrapping: only replace bare auth.uid() not already in (select ...)
|
||||
qual_new := regexp_replace(qual_new, '(?<!\(select )auth\.uid\(\)', '(select auth.uid())', 'gi');
|
||||
END IF;
|
||||
|
||||
-- Replace auth.uid() with (select auth.uid()) in WITH CHECK clause
|
||||
check_new := r.with_check;
|
||||
IF check_new IS NOT NULL THEN
|
||||
check_new := regexp_replace(check_new, '(?<!\(select )auth\.uid\(\)', '(select auth.uid())', 'gi');
|
||||
END IF;
|
||||
|
||||
-- Drop old policy
|
||||
EXECUTE format('DROP POLICY IF EXISTS %I ON %I.%I',
|
||||
r.policyname, r.schemaname, r.tablename);
|
||||
|
||||
-- Build CREATE POLICY command
|
||||
sql_cmd := format('CREATE POLICY %I ON %I.%I', r.policyname, r.schemaname, r.tablename);
|
||||
|
||||
-- AS PERMISSIVE/RESTRICTIVE
|
||||
IF r.permissive = 'false' THEN
|
||||
sql_cmd := sql_cmd || ' AS RESTRICTIVE';
|
||||
END IF;
|
||||
|
||||
-- FOR command
|
||||
sql_cmd := sql_cmd || ' FOR ' || r.policy_cmd;
|
||||
|
||||
-- TO roles
|
||||
sql_cmd := sql_cmd || ' TO ' || array_to_string(r.roles, ', ');
|
||||
|
||||
-- USING clause
|
||||
IF qual_new IS NOT NULL THEN
|
||||
sql_cmd := sql_cmd || ' USING (' || qual_new || ')';
|
||||
END IF;
|
||||
|
||||
-- WITH CHECK clause
|
||||
IF check_new IS NOT NULL THEN
|
||||
sql_cmd := sql_cmd || ' WITH CHECK (' || check_new || ')';
|
||||
END IF;
|
||||
|
||||
EXECUTE sql_cmd;
|
||||
|
||||
RAISE NOTICE 'Fixed initplan: %.% policy "%"', r.schemaname, r.tablename, r.policyname;
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
|
||||
-- ============================================================
|
||||
-- PART 2: Fix multiple_permissive_policies
|
||||
-- Pattern A: Tables with "Org members can view X" (SELECT) +
|
||||
-- "Editors can manage X" (FOR ALL) → drop the SELECT policy
|
||||
-- since FOR ALL already covers SELECT.
|
||||
-- Pattern B: Tables with "Platform admins full access" (FOR ALL) +
|
||||
-- "Editors can manage X" (FOR ALL) → merge platform admin
|
||||
-- check into the editors policy, drop the platform admin policy.
|
||||
-- Pattern C: Tables with "Org members can view X" (SELECT) +
|
||||
-- "Members can manage X" (FOR ALL) → same as Pattern A.
|
||||
-- ============================================================
|
||||
|
||||
-- --------------------------------------------------------
|
||||
-- Pattern A: Drop redundant SELECT-only policies
|
||||
-- These tables have both "view" (SELECT) and "manage" (FOR ALL)
|
||||
-- The FOR ALL already covers SELECT, making the view policy redundant
|
||||
-- --------------------------------------------------------
|
||||
|
||||
-- sponsors
|
||||
DROP POLICY IF EXISTS "Org members can view sponsors" ON public.sponsors;
|
||||
|
||||
-- sponsor_deliverables
|
||||
DROP POLICY IF EXISTS "Org members can view sponsor deliverables" ON public.sponsor_deliverables;
|
||||
|
||||
-- sponsor_tiers
|
||||
DROP POLICY IF EXISTS "Org members can view sponsor tiers" ON public.sponsor_tiers;
|
||||
|
||||
-- documents
|
||||
DROP POLICY IF EXISTS "Org members can view documents" ON public.documents;
|
||||
|
||||
-- kanban_boards
|
||||
DROP POLICY IF EXISTS "Org members can view boards" ON public.kanban_boards;
|
||||
|
||||
-- kanban_columns
|
||||
DROP POLICY IF EXISTS "Org members can view columns" ON public.kanban_columns;
|
||||
|
||||
-- kanban_cards
|
||||
DROP POLICY IF EXISTS "Org members can view cards" ON public.kanban_cards;
|
||||
|
||||
-- calendar_events
|
||||
DROP POLICY IF EXISTS "Org members can view events" ON public.calendar_events;
|
||||
|
||||
-- events
|
||||
DROP POLICY IF EXISTS "Org members can view events" ON public.events;
|
||||
|
||||
-- event_members
|
||||
DROP POLICY IF EXISTS "Org members can view event members" ON public.event_members;
|
||||
|
||||
-- event_roles
|
||||
DROP POLICY IF EXISTS "Org members can view event roles" ON public.event_roles;
|
||||
|
||||
-- event_departments
|
||||
DROP POLICY IF EXISTS "Org members can view event departments" ON public.event_departments;
|
||||
|
||||
-- event_member_departments
|
||||
DROP POLICY IF EXISTS "Org members can view member departments" ON public.event_member_departments;
|
||||
|
||||
-- event_task_columns
|
||||
DROP POLICY IF EXISTS "Org members can view event task columns" ON public.event_task_columns;
|
||||
|
||||
-- event_tasks
|
||||
DROP POLICY IF EXISTS "Org members can view event tasks" ON public.event_tasks;
|
||||
|
||||
-- department_dashboards
|
||||
DROP POLICY IF EXISTS "Org members can view department dashboards" ON public.department_dashboards;
|
||||
|
||||
-- dashboard_panels
|
||||
DROP POLICY IF EXISTS "Org members can view dashboard panels" ON public.dashboard_panels;
|
||||
|
||||
-- department_checklists
|
||||
DROP POLICY IF EXISTS "Org members can view department checklists" ON public.department_checklists;
|
||||
|
||||
-- department_checklist_items
|
||||
DROP POLICY IF EXISTS "Org members can view dept checklist items" ON public.department_checklist_items;
|
||||
|
||||
-- department_notes
|
||||
DROP POLICY IF EXISTS "Org members can view department notes" ON public.department_notes;
|
||||
|
||||
-- checklist_items
|
||||
DROP POLICY IF EXISTS "Org members can view checklist items" ON public.checklist_items;
|
||||
|
||||
-- budget_categories
|
||||
DROP POLICY IF EXISTS "Org members can view budget categories" ON public.budget_categories;
|
||||
|
||||
-- budget_items
|
||||
DROP POLICY IF EXISTS "Org members can view budget items" ON public.budget_items;
|
||||
|
||||
-- card_tags: "Users can view card tags" + "Members can manage card tags" (FOR ALL)
|
||||
DROP POLICY IF EXISTS "Users can view card tags in their orgs" ON public.card_tags;
|
||||
|
||||
-- document_locks: "Anyone can delete expired locks" + "Users can delete their own locks"
|
||||
-- Merge into single DELETE policy
|
||||
DROP POLICY IF EXISTS "Anyone can delete expired locks" ON public.document_locks;
|
||||
DROP POLICY IF EXISTS "Users can delete their own locks" ON public.document_locks;
|
||||
CREATE POLICY "Users can delete locks" ON public.document_locks
|
||||
FOR DELETE
|
||||
USING (
|
||||
user_id = (select auth.uid())
|
||||
OR last_heartbeat < (now() - interval '2 minutes')
|
||||
);
|
||||
|
||||
|
||||
-- --------------------------------------------------------
|
||||
-- Pattern B: Merge "Platform admins full access" into existing policies
|
||||
-- For tables that have both "Editors can manage X" and
|
||||
-- "Platform admins full access to X", we merge the admin check
|
||||
-- into the editors policy using OR is_platform_admin(), then
|
||||
-- drop the separate platform admin policy.
|
||||
-- --------------------------------------------------------
|
||||
|
||||
-- Note: The is_platform_admin() function was already fixed in migration 039
|
||||
-- to use (select auth.uid()). We just need to merge the policies.
|
||||
|
||||
-- For tables with platform admin policies, we need to update the
|
||||
-- "Editors can manage" policy to include OR (select public.is_platform_admin())
|
||||
-- then drop the platform admin policy.
|
||||
|
||||
-- calendar_events
|
||||
DROP POLICY IF EXISTS "Platform admins full access to calendar_events" ON public.calendar_events;
|
||||
DROP POLICY IF EXISTS "Editors can manage events" ON public.calendar_events;
|
||||
CREATE POLICY "Editors can manage events" ON public.calendar_events
|
||||
FOR ALL
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = calendar_events.org_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = calendar_events.org_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- documents
|
||||
DROP POLICY IF EXISTS "Platform admins full access to documents" ON public.documents;
|
||||
DROP POLICY IF EXISTS "Editors can manage documents" ON public.documents;
|
||||
CREATE POLICY "Editors can manage documents" ON public.documents
|
||||
FOR ALL
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = documents.org_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = documents.org_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- events
|
||||
DROP POLICY IF EXISTS "Platform admins full access to events" ON public.events;
|
||||
DROP POLICY IF EXISTS "Editors can manage events" ON public.events;
|
||||
CREATE POLICY "Editors can manage events" ON public.events
|
||||
FOR ALL
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = events.org_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = events.org_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- event_members
|
||||
DROP POLICY IF EXISTS "Platform admins full access to event_members" ON public.event_members;
|
||||
DROP POLICY IF EXISTS "Editors can manage event members" ON public.event_members;
|
||||
CREATE POLICY "Editors can manage event members" ON public.event_members
|
||||
FOR ALL
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE e.id = event_members.event_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE e.id = event_members.event_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- event_departments
|
||||
DROP POLICY IF EXISTS "Platform admins full access to event_departments" ON public.event_departments;
|
||||
DROP POLICY IF EXISTS "Editors can manage event departments" ON public.event_departments;
|
||||
CREATE POLICY "Editors can manage event departments" ON public.event_departments
|
||||
FOR ALL
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE e.id = event_departments.event_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE e.id = event_departments.event_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- kanban_boards
|
||||
DROP POLICY IF EXISTS "Platform admins full access to kanban_boards" ON public.kanban_boards;
|
||||
DROP POLICY IF EXISTS "Editors can manage boards" ON public.kanban_boards;
|
||||
CREATE POLICY "Editors can manage boards" ON public.kanban_boards
|
||||
FOR ALL
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = kanban_boards.org_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = kanban_boards.org_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- org_roles
|
||||
DROP POLICY IF EXISTS "Platform admins full access to org_roles" ON public.org_roles;
|
||||
-- org_roles has "Org members can view roles" + "Admins can manage roles"
|
||||
DROP POLICY IF EXISTS "Org members can view roles" ON public.org_roles;
|
||||
DROP POLICY IF EXISTS "Admins can manage roles" ON public.org_roles;
|
||||
CREATE POLICY "Admins can manage roles" ON public.org_roles
|
||||
FOR ALL
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_roles.org_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_roles.org_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
-- Org members still need to SELECT roles (for UI dropdowns etc)
|
||||
CREATE POLICY "Org members can view roles" ON public.org_roles
|
||||
FOR SELECT
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_roles.org_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- org_invites
|
||||
DROP POLICY IF EXISTS "Platform admins full access to org_invites" ON public.org_invites;
|
||||
-- org_invites has "Org members can view invites" + "Admins can manage invites"
|
||||
DROP POLICY IF EXISTS "Org members can view invites" ON public.org_invites;
|
||||
DROP POLICY IF EXISTS "Admins can manage invites" ON public.org_invites;
|
||||
CREATE POLICY "Admins can manage invites" ON public.org_invites
|
||||
FOR ALL
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_invites.org_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_invites.org_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
-- Org members still need to SELECT invites
|
||||
CREATE POLICY "Org members can view invites" ON public.org_invites
|
||||
FOR SELECT
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_invites.org_id
|
||||
AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- organizations
|
||||
DROP POLICY IF EXISTS "Platform admins full access to organizations" ON public.organizations;
|
||||
-- organizations already has separate view/update/delete policies, platform admin just adds another FOR ALL
|
||||
-- Merge into existing policies by adding OR is_platform_admin()
|
||||
DROP POLICY IF EXISTS "Members can view their organizations" ON public.organizations;
|
||||
CREATE POLICY "Members can view their organizations" ON public.organizations
|
||||
FOR SELECT
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = organizations.id
|
||||
AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
DROP POLICY IF EXISTS "Owners and admins can update organizations" ON public.organizations;
|
||||
CREATE POLICY "Owners and admins can update organizations" ON public.organizations
|
||||
FOR UPDATE
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = organizations.id
|
||||
AND om.user_id = (select auth.uid())
|
||||
AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = organizations.id
|
||||
AND om.user_id = (select auth.uid())
|
||||
AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
|
||||
DROP POLICY IF EXISTS "Owners can delete organizations" ON public.organizations;
|
||||
CREATE POLICY "Owners can delete organizations" ON public.organizations
|
||||
FOR DELETE
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = organizations.id
|
||||
AND om.user_id = (select auth.uid())
|
||||
AND om.role = 'owner'
|
||||
)
|
||||
);
|
||||
|
||||
-- org_members
|
||||
DROP POLICY IF EXISTS "Platform admins full access to org_members" ON public.org_members;
|
||||
-- org_members has separate view/manage/delete policies + Allow member inserts
|
||||
-- Just add platform admin to the view policy
|
||||
DROP POLICY IF EXISTS "Members can view org members" ON public.org_members;
|
||||
CREATE POLICY "Members can view org members" ON public.org_members
|
||||
FOR SELECT
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om2
|
||||
WHERE om2.org_id = org_members.org_id
|
||||
AND om2.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
DROP POLICY IF EXISTS "Owners and admins can manage members" ON public.org_members;
|
||||
CREATE POLICY "Owners and admins can manage members" ON public.org_members
|
||||
FOR UPDATE
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om2
|
||||
WHERE om2.org_id = org_members.org_id
|
||||
AND om2.user_id = (select auth.uid())
|
||||
AND om2.role IN ('owner', 'admin')
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om2
|
||||
WHERE om2.org_id = org_members.org_id
|
||||
AND om2.user_id = (select auth.uid())
|
||||
AND om2.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
|
||||
DROP POLICY IF EXISTS "Owners and admins can delete members" ON public.org_members;
|
||||
CREATE POLICY "Owners and admins can delete members" ON public.org_members
|
||||
FOR DELETE
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om2
|
||||
WHERE om2.org_id = org_members.org_id
|
||||
AND om2.user_id = (select auth.uid())
|
||||
AND om2.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
-- ============================================================
|
||||
-- PART 3: Run the initplan fixer AGAIN after Part 2
|
||||
-- Part 2 created new policies that may still use bare auth.uid()
|
||||
-- in the USING/WITH CHECK from the original policy definitions.
|
||||
-- This second pass catches any remaining bare auth.uid() calls.
|
||||
-- ============================================================
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
r record;
|
||||
qual_new text;
|
||||
check_new text;
|
||||
sql_cmd text;
|
||||
BEGIN
|
||||
FOR r IN
|
||||
SELECT
|
||||
schemaname,
|
||||
tablename,
|
||||
policyname,
|
||||
permissive,
|
||||
roles,
|
||||
cmd AS policy_cmd,
|
||||
qual,
|
||||
with_check
|
||||
FROM pg_policies
|
||||
WHERE schemaname = 'public'
|
||||
AND (
|
||||
qual ~ 'auth\.uid\(\)' AND qual !~ '\(\s*select\s+auth\.uid\(\)\s*\)'
|
||||
OR
|
||||
with_check ~ 'auth\.uid\(\)' AND with_check !~ '\(\s*select\s+auth\.uid\(\)\s*\)'
|
||||
)
|
||||
LOOP
|
||||
qual_new := r.qual;
|
||||
IF qual_new IS NOT NULL THEN
|
||||
qual_new := regexp_replace(qual_new, '(?<!\(select )auth\.uid\(\)', '(select auth.uid())', 'gi');
|
||||
END IF;
|
||||
|
||||
check_new := r.with_check;
|
||||
IF check_new IS NOT NULL THEN
|
||||
check_new := regexp_replace(check_new, '(?<!\(select )auth\.uid\(\)', '(select auth.uid())', 'gi');
|
||||
END IF;
|
||||
|
||||
EXECUTE format('DROP POLICY IF EXISTS %I ON %I.%I',
|
||||
r.policyname, r.schemaname, r.tablename);
|
||||
|
||||
sql_cmd := format('CREATE POLICY %I ON %I.%I', r.policyname, r.schemaname, r.tablename);
|
||||
|
||||
IF r.permissive = 'false' THEN
|
||||
sql_cmd := sql_cmd || ' AS RESTRICTIVE';
|
||||
END IF;
|
||||
|
||||
sql_cmd := sql_cmd || ' FOR ' || r.policy_cmd;
|
||||
sql_cmd := sql_cmd || ' TO ' || array_to_string(r.roles, ', ');
|
||||
|
||||
IF qual_new IS NOT NULL THEN
|
||||
sql_cmd := sql_cmd || ' USING (' || qual_new || ')';
|
||||
END IF;
|
||||
|
||||
IF check_new IS NOT NULL THEN
|
||||
sql_cmd := sql_cmd || ' WITH CHECK (' || check_new || ')';
|
||||
END IF;
|
||||
|
||||
EXECUTE sql_cmd;
|
||||
|
||||
RAISE NOTICE 'Fixed initplan (pass 2): %.% policy "%"', r.schemaname, r.tablename, r.policyname;
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
975
supabase/migrations/052_fix_rls_policies.sql
Normal file
975
supabase/migrations/052_fix_rls_policies.sql
Normal file
@@ -0,0 +1,975 @@
|
||||
-- ============================================================
|
||||
-- Migration 052: Fix all RLS policies after 051 corruption
|
||||
-- Drops ALL policies on public tables and recreates them cleanly
|
||||
-- with (select auth.uid()) everywhere. Also consolidates
|
||||
-- multiple permissive policies per table.
|
||||
-- ============================================================
|
||||
|
||||
-- ============================================================
|
||||
-- STEP 1: Drop ALL existing policies on all public tables
|
||||
-- ============================================================
|
||||
DO $$
|
||||
DECLARE
|
||||
r record;
|
||||
BEGIN
|
||||
FOR r IN
|
||||
SELECT schemaname, tablename, policyname
|
||||
FROM pg_policies
|
||||
WHERE schemaname = 'public'
|
||||
LOOP
|
||||
EXECUTE format('DROP POLICY IF EXISTS %I ON %I.%I',
|
||||
r.policyname, r.schemaname, r.tablename);
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
-- ============================================================
|
||||
-- STEP 2: Recreate ALL policies with correct (select auth.uid())
|
||||
-- ============================================================
|
||||
|
||||
-- ── profiles ──
|
||||
CREATE POLICY "Profiles are viewable by everyone" ON public.profiles
|
||||
FOR SELECT USING (true);
|
||||
CREATE POLICY "Users can update own profile" ON public.profiles
|
||||
FOR UPDATE USING ((select auth.uid()) = id);
|
||||
CREATE POLICY "Platform admins can update profiles" ON public.profiles
|
||||
FOR UPDATE USING ((select public.is_platform_admin()));
|
||||
|
||||
-- ── organizations ──
|
||||
CREATE POLICY "Anyone can create organizations" ON public.organizations
|
||||
FOR INSERT WITH CHECK (true);
|
||||
CREATE POLICY "Members can view their organizations" ON public.organizations
|
||||
FOR SELECT USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = organizations.id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Owners and admins can update organizations" ON public.organizations
|
||||
FOR UPDATE
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = organizations.id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = organizations.id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Owners can delete organizations" ON public.organizations
|
||||
FOR DELETE USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = organizations.id AND om.user_id = (select auth.uid()) AND om.role = 'owner'
|
||||
)
|
||||
);
|
||||
|
||||
-- ── org_members ──
|
||||
CREATE POLICY "Members can view org members" ON public.org_members
|
||||
FOR SELECT USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om2
|
||||
WHERE om2.org_id = org_members.org_id AND om2.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Allow member inserts" ON public.org_members
|
||||
FOR INSERT WITH CHECK (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_members.org_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
OR org_members.user_id = (select auth.uid())
|
||||
);
|
||||
CREATE POLICY "Owners and admins can manage members" ON public.org_members
|
||||
FOR UPDATE
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om2
|
||||
WHERE om2.org_id = org_members.org_id AND om2.user_id = (select auth.uid()) AND om2.role IN ('owner', 'admin')
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om2
|
||||
WHERE om2.org_id = org_members.org_id AND om2.user_id = (select auth.uid()) AND om2.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Owners and admins can delete members" ON public.org_members
|
||||
FOR DELETE USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om2
|
||||
WHERE om2.org_id = org_members.org_id AND om2.user_id = (select auth.uid()) AND om2.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
|
||||
-- ── org_roles ──
|
||||
CREATE POLICY "Org members can view roles" ON public.org_roles
|
||||
FOR SELECT USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_roles.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Admins can manage roles" ON public.org_roles
|
||||
FOR ALL USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_roles.org_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
|
||||
-- ── org_invites ──
|
||||
CREATE POLICY "Org members can view invites" ON public.org_invites
|
||||
FOR SELECT USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_invites.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Anyone can view invite by token" ON public.org_invites
|
||||
FOR SELECT USING (true);
|
||||
CREATE POLICY "Admins can manage invites" ON public.org_invites
|
||||
FOR ALL USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_invites.org_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
|
||||
-- ── documents ──
|
||||
CREATE POLICY "Editors can manage documents" ON public.documents
|
||||
FOR ALL USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = documents.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = documents.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── document_locks ──
|
||||
CREATE POLICY "Org members can view document locks" ON public.document_locks
|
||||
FOR SELECT USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.documents d
|
||||
JOIN public.org_members om ON d.org_id = om.org_id
|
||||
WHERE d.id = document_locks.document_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Users can insert their own locks" ON public.document_locks
|
||||
FOR INSERT WITH CHECK (user_id = (select auth.uid()));
|
||||
CREATE POLICY "Users can update their own locks" ON public.document_locks
|
||||
FOR UPDATE USING (user_id = (select auth.uid()));
|
||||
CREATE POLICY "Users can delete locks" ON public.document_locks
|
||||
FOR DELETE USING (
|
||||
user_id = (select auth.uid())
|
||||
OR last_heartbeat < (now() - interval '2 minutes')
|
||||
);
|
||||
|
||||
-- ── kanban_boards ──
|
||||
CREATE POLICY "Editors can manage boards" ON public.kanban_boards
|
||||
FOR ALL USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = kanban_boards.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = kanban_boards.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── kanban_columns ──
|
||||
CREATE POLICY "Editors can manage columns" ON public.kanban_columns
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.kanban_boards b
|
||||
JOIN public.org_members om ON b.org_id = om.org_id
|
||||
WHERE b.id = kanban_columns.board_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── kanban_cards ──
|
||||
CREATE POLICY "Editors can manage cards" ON public.kanban_cards
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.kanban_columns c
|
||||
JOIN public.kanban_boards b ON c.board_id = b.id
|
||||
JOIN public.org_members om ON b.org_id = om.org_id
|
||||
WHERE c.id = kanban_cards.column_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── card_assignees ──
|
||||
CREATE POLICY "Card assignees inherit card access" ON public.card_assignees
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards kc
|
||||
JOIN public.kanban_columns kcol ON kcol.id = kc.column_id
|
||||
JOIN public.kanban_boards kb ON kb.id = kcol.board_id
|
||||
JOIN public.org_members om ON om.org_id = kb.org_id
|
||||
WHERE kc.id = card_assignees.card_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── checklist_items (card checklists) ──
|
||||
CREATE POLICY "Editors can manage checklist items" ON public.checklist_items
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards c
|
||||
JOIN public.kanban_columns col ON c.column_id = col.id
|
||||
JOIN public.kanban_boards b ON col.board_id = b.id
|
||||
JOIN public.org_members om ON b.org_id = om.org_id
|
||||
WHERE c.id = checklist_items.card_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── kanban_checklist_items ──
|
||||
CREATE POLICY "Checklist items inherit card access" ON public.kanban_checklist_items
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards c
|
||||
JOIN public.kanban_columns col ON c.column_id = col.id
|
||||
JOIN public.kanban_boards b ON col.board_id = b.id
|
||||
JOIN public.org_members m ON b.org_id = m.org_id
|
||||
WHERE c.id = kanban_checklist_items.card_id AND m.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── kanban_comments ──
|
||||
CREATE POLICY "Comments inherit card access" ON public.kanban_comments
|
||||
FOR SELECT USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards c
|
||||
JOIN public.kanban_columns col ON c.column_id = col.id
|
||||
JOIN public.kanban_boards b ON col.board_id = b.id
|
||||
JOIN public.org_members m ON b.org_id = m.org_id
|
||||
WHERE c.id = kanban_comments.card_id AND m.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Users can insert own comments" ON public.kanban_comments
|
||||
FOR INSERT WITH CHECK (
|
||||
user_id = (select auth.uid()) AND
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards c
|
||||
JOIN public.kanban_columns col ON c.column_id = col.id
|
||||
JOIN public.kanban_boards b ON col.board_id = b.id
|
||||
JOIN public.org_members m ON b.org_id = m.org_id
|
||||
WHERE c.id = kanban_comments.card_id AND m.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Users can update own comments" ON public.kanban_comments
|
||||
FOR UPDATE USING (user_id = (select auth.uid()));
|
||||
CREATE POLICY "Users can delete own comments" ON public.kanban_comments
|
||||
FOR DELETE USING (user_id = (select auth.uid()));
|
||||
|
||||
-- ── kanban_labels ──
|
||||
CREATE POLICY "Labels accessible to org members" ON public.kanban_labels
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members m
|
||||
WHERE m.org_id = kanban_labels.org_id AND m.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── card_labels ──
|
||||
CREATE POLICY "Card labels inherit card access" ON public.card_labels
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards c
|
||||
JOIN public.kanban_columns col ON c.column_id = col.id
|
||||
JOIN public.kanban_boards b ON col.board_id = b.id
|
||||
JOIN public.org_members m ON b.org_id = m.org_id
|
||||
WHERE c.id = card_labels.card_id AND m.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── tags ──
|
||||
CREATE POLICY "Users can view tags in their orgs" ON public.tags
|
||||
FOR SELECT USING (
|
||||
org_id IN (SELECT org_id FROM public.org_members WHERE user_id = (select auth.uid()))
|
||||
);
|
||||
CREATE POLICY "Admins can manage tags" ON public.tags
|
||||
FOR ALL USING (
|
||||
org_id IN (
|
||||
SELECT org_id FROM public.org_members
|
||||
WHERE user_id = (select auth.uid()) AND role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
|
||||
-- ── card_tags ──
|
||||
CREATE POLICY "Members can manage card tags" ON public.card_tags
|
||||
FOR ALL USING (
|
||||
tag_id IN (
|
||||
SELECT id FROM public.tags WHERE org_id IN (
|
||||
SELECT org_id FROM public.org_members WHERE user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
-- ── teams ──
|
||||
CREATE POLICY "Users can view teams in their orgs" ON public.teams
|
||||
FOR SELECT USING (
|
||||
org_id IN (SELECT org_id FROM public.org_members WHERE user_id = (select auth.uid()))
|
||||
);
|
||||
CREATE POLICY "Admins can manage teams" ON public.teams
|
||||
FOR ALL USING (
|
||||
org_id IN (
|
||||
SELECT org_id FROM public.org_members
|
||||
WHERE user_id = (select auth.uid()) AND role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
|
||||
-- ── team_members ──
|
||||
CREATE POLICY "Users can view team members in their orgs" ON public.team_members
|
||||
FOR SELECT USING (
|
||||
team_id IN (
|
||||
SELECT id FROM public.teams WHERE org_id IN (
|
||||
SELECT org_id FROM public.org_members WHERE user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Admins can manage team members" ON public.team_members
|
||||
FOR ALL USING (
|
||||
team_id IN (
|
||||
SELECT id FROM public.teams WHERE org_id IN (
|
||||
SELECT org_id FROM public.org_members
|
||||
WHERE user_id = (select auth.uid()) AND role IN ('owner', 'admin')
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
-- ── calendar_events ──
|
||||
CREATE POLICY "Editors can manage events" ON public.calendar_events
|
||||
FOR ALL USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = calendar_events.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = calendar_events.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── event_attendees ──
|
||||
CREATE POLICY "Org members can manage event attendees" ON public.event_attendees
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE e.id = event_attendees.event_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── org_google_calendars ──
|
||||
CREATE POLICY "Members can view org calendar" ON public.org_google_calendars
|
||||
FOR SELECT USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members
|
||||
WHERE org_members.org_id = org_google_calendars.org_id AND org_members.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Admins can manage org calendar" ON public.org_google_calendars
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members
|
||||
WHERE org_members.org_id = org_google_calendars.org_id
|
||||
AND org_members.user_id = (select auth.uid())
|
||||
AND org_members.role IN ('admin', 'owner')
|
||||
)
|
||||
);
|
||||
|
||||
-- ── activity_log ──
|
||||
CREATE POLICY "Users can view org activity" ON public.activity_log
|
||||
FOR SELECT USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members m
|
||||
WHERE m.org_id = activity_log.org_id AND m.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Users can insert own activity" ON public.activity_log
|
||||
FOR INSERT WITH CHECK (user_id = (select auth.uid()));
|
||||
|
||||
-- ── user_preferences ──
|
||||
CREATE POLICY "Users can manage own preferences" ON public.user_preferences
|
||||
FOR ALL USING (user_id = (select auth.uid()));
|
||||
|
||||
-- ── matrix_credentials ──
|
||||
CREATE POLICY "Users can read own matrix credentials" ON public.matrix_credentials
|
||||
FOR SELECT USING ((select auth.uid()) = user_id);
|
||||
CREATE POLICY "Users can insert own matrix credentials" ON public.matrix_credentials
|
||||
FOR INSERT WITH CHECK ((select auth.uid()) = user_id);
|
||||
CREATE POLICY "Users can update own matrix credentials" ON public.matrix_credentials
|
||||
FOR UPDATE USING ((select auth.uid()) = user_id);
|
||||
CREATE POLICY "Users can delete own matrix credentials" ON public.matrix_credentials
|
||||
FOR DELETE USING ((select auth.uid()) = user_id);
|
||||
|
||||
-- ── events ──
|
||||
CREATE POLICY "Editors can manage events" ON public.events
|
||||
FOR ALL USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = events.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = events.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── event_members ──
|
||||
CREATE POLICY "Editors can manage event members" ON public.event_members
|
||||
FOR ALL USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE e.id = event_members.event_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE e.id = event_members.event_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── event_roles ──
|
||||
CREATE POLICY "Editors can manage event roles" ON public.event_roles
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE e.id = event_roles.event_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── event_departments ──
|
||||
CREATE POLICY "Editors can manage event departments" ON public.event_departments
|
||||
FOR ALL USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE e.id = event_departments.event_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE e.id = event_departments.event_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── event_member_departments ──
|
||||
CREATE POLICY "Editors can manage member departments" ON public.event_member_departments
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.event_members em
|
||||
JOIN public.events e ON em.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE em.id = event_member_departments.event_member_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── event_task_columns ──
|
||||
CREATE POLICY "Editors can manage event task columns" ON public.event_task_columns
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE e.id = event_task_columns.event_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── event_tasks ──
|
||||
CREATE POLICY "Editors can manage event tasks" ON public.event_tasks
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE e.id = event_tasks.event_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── department_dashboards ──
|
||||
CREATE POLICY "Editors can manage department dashboards" ON public.department_dashboards
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = department_dashboards.department_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── dashboard_panels ──
|
||||
CREATE POLICY "Editors can manage dashboard panels" ON public.dashboard_panels
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.department_dashboards dd
|
||||
JOIN public.event_departments ed ON dd.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE dd.id = dashboard_panels.dashboard_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── department_checklists ──
|
||||
CREATE POLICY "Editors can manage department checklists" ON public.department_checklists
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = department_checklists.department_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── department_checklist_items ──
|
||||
CREATE POLICY "Editors can manage dept checklist items" ON public.department_checklist_items
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.department_checklists dc
|
||||
JOIN public.event_departments ed ON dc.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE dc.id = department_checklist_items.checklist_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── department_notes ──
|
||||
CREATE POLICY "Editors can manage department notes" ON public.department_notes
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = department_notes.department_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── schedule_stages ──
|
||||
CREATE POLICY "schedule_stages_select" ON public.schedule_stages FOR SELECT
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = schedule_stages.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "schedule_stages_insert" ON public.schedule_stages FOR INSERT
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = schedule_stages.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "schedule_stages_update" ON public.schedule_stages FOR UPDATE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = schedule_stages.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "schedule_stages_delete" ON public.schedule_stages FOR DELETE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = schedule_stages.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
|
||||
-- ── schedule_blocks ──
|
||||
CREATE POLICY "schedule_blocks_select" ON public.schedule_blocks FOR SELECT
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = schedule_blocks.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "schedule_blocks_insert" ON public.schedule_blocks FOR INSERT
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = schedule_blocks.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "schedule_blocks_update" ON public.schedule_blocks FOR UPDATE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = schedule_blocks.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "schedule_blocks_delete" ON public.schedule_blocks FOR DELETE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = schedule_blocks.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
|
||||
-- ── department_contacts ──
|
||||
CREATE POLICY "department_contacts_select" ON public.department_contacts FOR SELECT
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_contacts.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "department_contacts_insert" ON public.department_contacts FOR INSERT
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_contacts.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "department_contacts_update" ON public.department_contacts FOR UPDATE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_contacts.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "department_contacts_delete" ON public.department_contacts FOR DELETE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_contacts.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
|
||||
-- ── budget_categories ──
|
||||
CREATE POLICY "Editors can manage budget categories" ON public.budget_categories
|
||||
FOR ALL USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = budget_categories.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
|
||||
-- ── budget_items ──
|
||||
CREATE POLICY "Editors can manage budget items" ON public.budget_items
|
||||
FOR ALL USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = budget_items.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
|
||||
-- ── sponsor_tiers ──
|
||||
CREATE POLICY "Editors can manage sponsor tiers" ON public.sponsor_tiers
|
||||
FOR ALL USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = sponsor_tiers.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
|
||||
-- ── sponsors ──
|
||||
CREATE POLICY "Editors can manage sponsors" ON public.sponsors
|
||||
FOR ALL USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = sponsors.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
|
||||
-- ── sponsor_deliverables ──
|
||||
CREATE POLICY "Editors can manage sponsor deliverables" ON public.sponsor_deliverables
|
||||
FOR ALL USING (EXISTS (
|
||||
SELECT 1 FROM public.sponsors s
|
||||
JOIN public.event_departments ed ON s.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE s.id = sponsor_deliverables.sponsor_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
|
||||
-- ── sponsor_allocations ──
|
||||
CREATE POLICY "sponsor_allocations_select" ON public.sponsor_allocations FOR SELECT
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = sponsor_allocations.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "sponsor_allocations_insert" ON public.sponsor_allocations FOR INSERT
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = sponsor_allocations.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "sponsor_allocations_update" ON public.sponsor_allocations FOR UPDATE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = sponsor_allocations.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "sponsor_allocations_delete" ON public.sponsor_allocations FOR DELETE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = sponsor_allocations.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
|
||||
-- ── org_contacts ──
|
||||
CREATE POLICY "org_contacts_select" ON public.org_contacts FOR SELECT
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_contacts.org_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "org_contacts_insert" ON public.org_contacts FOR INSERT
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_contacts.org_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "org_contacts_update" ON public.org_contacts FOR UPDATE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_contacts.org_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "org_contacts_delete" ON public.org_contacts FOR DELETE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_contacts.org_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
|
||||
-- ── department_pinned_contacts ──
|
||||
CREATE POLICY "dept_pinned_contacts_select" ON public.department_pinned_contacts FOR SELECT
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_pinned_contacts.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "dept_pinned_contacts_insert" ON public.department_pinned_contacts FOR INSERT
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_pinned_contacts.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "dept_pinned_contacts_delete" ON public.department_pinned_contacts FOR DELETE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_pinned_contacts.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
|
||||
-- ── map_layers ──
|
||||
CREATE POLICY "Org members can view map layers" ON public.map_layers FOR SELECT
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = map_layers.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can insert map layers" ON public.map_layers FOR INSERT
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = map_layers.department_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can update map layers" ON public.map_layers FOR UPDATE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = map_layers.department_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
))
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = map_layers.department_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can delete map layers" ON public.map_layers FOR DELETE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = map_layers.department_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
|
||||
-- ── map_pins ──
|
||||
CREATE POLICY "Org members can view map pins" ON public.map_pins FOR SELECT
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_pins.layer_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can insert map pins" ON public.map_pins FOR INSERT
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_pins.layer_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can update map pins" ON public.map_pins FOR UPDATE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_pins.layer_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
))
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_pins.layer_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can delete map pins" ON public.map_pins FOR DELETE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_pins.layer_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
|
||||
-- ── map_shapes ──
|
||||
CREATE POLICY "Org members can view map shapes" ON public.map_shapes FOR SELECT
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_shapes.layer_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can insert map shapes" ON public.map_shapes FOR INSERT
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_shapes.layer_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can update map shapes" ON public.map_shapes FOR UPDATE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_shapes.layer_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
))
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_shapes.layer_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can delete map shapes" ON public.map_shapes FOR DELETE
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_shapes.layer_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
972
supabase/migrations/053_fix_rls_authenticated.sql
Normal file
972
supabase/migrations/053_fix_rls_authenticated.sql
Normal file
@@ -0,0 +1,972 @@
|
||||
-- ============================================================
|
||||
-- Migration 053: Add TO authenticated to all RLS policies
|
||||
-- Per Supabase docs, policies should specify TO authenticated
|
||||
-- to avoid running auth.uid() checks for anon users (returns NULL).
|
||||
-- Also adds TO anon where public access is needed.
|
||||
-- ============================================================
|
||||
|
||||
-- Drop all policies again (clean slate)
|
||||
DO $$
|
||||
DECLARE
|
||||
r record;
|
||||
BEGIN
|
||||
FOR r IN
|
||||
SELECT schemaname, tablename, policyname
|
||||
FROM pg_policies
|
||||
WHERE schemaname = 'public'
|
||||
LOOP
|
||||
EXECUTE format('DROP POLICY IF EXISTS %I ON %I.%I',
|
||||
r.policyname, r.schemaname, r.tablename);
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
-- ── profiles ──
|
||||
CREATE POLICY "Profiles are viewable by everyone" ON public.profiles
|
||||
FOR SELECT TO authenticated USING (true);
|
||||
CREATE POLICY "Users can update own profile" ON public.profiles
|
||||
FOR UPDATE TO authenticated USING ((select auth.uid()) = id);
|
||||
CREATE POLICY "Platform admins can update profiles" ON public.profiles
|
||||
FOR UPDATE TO authenticated USING ((select public.is_platform_admin()));
|
||||
|
||||
-- ── organizations ──
|
||||
CREATE POLICY "Anyone can create organizations" ON public.organizations
|
||||
FOR INSERT TO authenticated WITH CHECK (true);
|
||||
CREATE POLICY "Members can view their organizations" ON public.organizations
|
||||
FOR SELECT TO authenticated USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = organizations.id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Owners and admins can update organizations" ON public.organizations
|
||||
FOR UPDATE TO authenticated
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = organizations.id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = organizations.id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Owners can delete organizations" ON public.organizations
|
||||
FOR DELETE TO authenticated USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = organizations.id AND om.user_id = (select auth.uid()) AND om.role = 'owner'
|
||||
)
|
||||
);
|
||||
|
||||
-- ── org_members ──
|
||||
CREATE POLICY "Members can view org members" ON public.org_members
|
||||
FOR SELECT TO authenticated USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om2
|
||||
WHERE om2.org_id = org_members.org_id AND om2.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Allow member inserts" ON public.org_members
|
||||
FOR INSERT TO authenticated WITH CHECK (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_members.org_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
OR org_members.user_id = (select auth.uid())
|
||||
);
|
||||
CREATE POLICY "Owners and admins can manage members" ON public.org_members
|
||||
FOR UPDATE TO authenticated
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om2
|
||||
WHERE om2.org_id = org_members.org_id AND om2.user_id = (select auth.uid()) AND om2.role IN ('owner', 'admin')
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om2
|
||||
WHERE om2.org_id = org_members.org_id AND om2.user_id = (select auth.uid()) AND om2.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Owners and admins can delete members" ON public.org_members
|
||||
FOR DELETE TO authenticated USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om2
|
||||
WHERE om2.org_id = org_members.org_id AND om2.user_id = (select auth.uid()) AND om2.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
|
||||
-- ── org_roles ──
|
||||
CREATE POLICY "Org members can view roles" ON public.org_roles
|
||||
FOR SELECT TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_roles.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Admins can manage roles" ON public.org_roles
|
||||
FOR ALL TO authenticated USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_roles.org_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
|
||||
-- ── org_invites ──
|
||||
CREATE POLICY "Org members can view invites" ON public.org_invites
|
||||
FOR SELECT TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_invites.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Anyone can view invite by token" ON public.org_invites
|
||||
FOR SELECT TO anon, authenticated USING (true);
|
||||
CREATE POLICY "Admins can manage invites" ON public.org_invites
|
||||
FOR ALL TO authenticated USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_invites.org_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
|
||||
-- ── documents ──
|
||||
CREATE POLICY "Editors can manage documents" ON public.documents
|
||||
FOR ALL TO authenticated USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = documents.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = documents.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── document_locks ──
|
||||
CREATE POLICY "Org members can view document locks" ON public.document_locks
|
||||
FOR SELECT TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.documents d
|
||||
JOIN public.org_members om ON d.org_id = om.org_id
|
||||
WHERE d.id = document_locks.document_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Users can insert their own locks" ON public.document_locks
|
||||
FOR INSERT TO authenticated WITH CHECK (user_id = (select auth.uid()));
|
||||
CREATE POLICY "Users can update their own locks" ON public.document_locks
|
||||
FOR UPDATE TO authenticated USING (user_id = (select auth.uid()));
|
||||
CREATE POLICY "Users can delete locks" ON public.document_locks
|
||||
FOR DELETE TO authenticated USING (
|
||||
user_id = (select auth.uid())
|
||||
OR last_heartbeat < (now() - interval '2 minutes')
|
||||
);
|
||||
|
||||
-- ── kanban_boards ──
|
||||
CREATE POLICY "Editors can manage boards" ON public.kanban_boards
|
||||
FOR ALL TO authenticated USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = kanban_boards.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = kanban_boards.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── kanban_columns ──
|
||||
CREATE POLICY "Editors can manage columns" ON public.kanban_columns
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.kanban_boards b
|
||||
JOIN public.org_members om ON b.org_id = om.org_id
|
||||
WHERE b.id = kanban_columns.board_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── kanban_cards ──
|
||||
CREATE POLICY "Editors can manage cards" ON public.kanban_cards
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.kanban_columns c
|
||||
JOIN public.kanban_boards b ON c.board_id = b.id
|
||||
JOIN public.org_members om ON b.org_id = om.org_id
|
||||
WHERE c.id = kanban_cards.column_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── card_assignees ──
|
||||
CREATE POLICY "Card assignees inherit card access" ON public.card_assignees
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards kc
|
||||
JOIN public.kanban_columns kcol ON kcol.id = kc.column_id
|
||||
JOIN public.kanban_boards kb ON kb.id = kcol.board_id
|
||||
JOIN public.org_members om ON om.org_id = kb.org_id
|
||||
WHERE kc.id = card_assignees.card_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── checklist_items (card checklists) ──
|
||||
CREATE POLICY "Editors can manage checklist items" ON public.checklist_items
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards c
|
||||
JOIN public.kanban_columns col ON c.column_id = col.id
|
||||
JOIN public.kanban_boards b ON col.board_id = b.id
|
||||
JOIN public.org_members om ON b.org_id = om.org_id
|
||||
WHERE c.id = checklist_items.card_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── kanban_checklist_items ──
|
||||
CREATE POLICY "Checklist items inherit card access" ON public.kanban_checklist_items
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards c
|
||||
JOIN public.kanban_columns col ON c.column_id = col.id
|
||||
JOIN public.kanban_boards b ON col.board_id = b.id
|
||||
JOIN public.org_members m ON b.org_id = m.org_id
|
||||
WHERE c.id = kanban_checklist_items.card_id AND m.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── kanban_comments ──
|
||||
CREATE POLICY "Comments inherit card access" ON public.kanban_comments
|
||||
FOR SELECT TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards c
|
||||
JOIN public.kanban_columns col ON c.column_id = col.id
|
||||
JOIN public.kanban_boards b ON col.board_id = b.id
|
||||
JOIN public.org_members m ON b.org_id = m.org_id
|
||||
WHERE c.id = kanban_comments.card_id AND m.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Users can insert own comments" ON public.kanban_comments
|
||||
FOR INSERT TO authenticated WITH CHECK (
|
||||
user_id = (select auth.uid()) AND
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards c
|
||||
JOIN public.kanban_columns col ON c.column_id = col.id
|
||||
JOIN public.kanban_boards b ON col.board_id = b.id
|
||||
JOIN public.org_members m ON b.org_id = m.org_id
|
||||
WHERE c.id = kanban_comments.card_id AND m.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Users can update own comments" ON public.kanban_comments
|
||||
FOR UPDATE TO authenticated USING (user_id = (select auth.uid()));
|
||||
CREATE POLICY "Users can delete own comments" ON public.kanban_comments
|
||||
FOR DELETE TO authenticated USING (user_id = (select auth.uid()));
|
||||
|
||||
-- ── kanban_labels ──
|
||||
CREATE POLICY "Labels accessible to org members" ON public.kanban_labels
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members m
|
||||
WHERE m.org_id = kanban_labels.org_id AND m.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── card_labels ──
|
||||
CREATE POLICY "Card labels inherit card access" ON public.card_labels
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards c
|
||||
JOIN public.kanban_columns col ON c.column_id = col.id
|
||||
JOIN public.kanban_boards b ON col.board_id = b.id
|
||||
JOIN public.org_members m ON b.org_id = m.org_id
|
||||
WHERE c.id = card_labels.card_id AND m.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── tags ──
|
||||
CREATE POLICY "Users can view tags in their orgs" ON public.tags
|
||||
FOR SELECT TO authenticated USING (
|
||||
org_id IN (SELECT org_id FROM public.org_members WHERE user_id = (select auth.uid()))
|
||||
);
|
||||
CREATE POLICY "Admins can manage tags" ON public.tags
|
||||
FOR ALL TO authenticated USING (
|
||||
org_id IN (
|
||||
SELECT org_id FROM public.org_members
|
||||
WHERE user_id = (select auth.uid()) AND role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
|
||||
-- ── card_tags ──
|
||||
CREATE POLICY "Members can manage card tags" ON public.card_tags
|
||||
FOR ALL TO authenticated USING (
|
||||
tag_id IN (
|
||||
SELECT id FROM public.tags WHERE org_id IN (
|
||||
SELECT org_id FROM public.org_members WHERE user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
-- ── teams ──
|
||||
CREATE POLICY "Users can view teams in their orgs" ON public.teams
|
||||
FOR SELECT TO authenticated USING (
|
||||
org_id IN (SELECT org_id FROM public.org_members WHERE user_id = (select auth.uid()))
|
||||
);
|
||||
CREATE POLICY "Admins can manage teams" ON public.teams
|
||||
FOR ALL TO authenticated USING (
|
||||
org_id IN (
|
||||
SELECT org_id FROM public.org_members
|
||||
WHERE user_id = (select auth.uid()) AND role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
|
||||
-- ── team_members ──
|
||||
CREATE POLICY "Users can view team members in their orgs" ON public.team_members
|
||||
FOR SELECT TO authenticated USING (
|
||||
team_id IN (
|
||||
SELECT id FROM public.teams WHERE org_id IN (
|
||||
SELECT org_id FROM public.org_members WHERE user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Admins can manage team members" ON public.team_members
|
||||
FOR ALL TO authenticated USING (
|
||||
team_id IN (
|
||||
SELECT id FROM public.teams WHERE org_id IN (
|
||||
SELECT org_id FROM public.org_members
|
||||
WHERE user_id = (select auth.uid()) AND role IN ('owner', 'admin')
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
-- ── calendar_events ──
|
||||
CREATE POLICY "Editors can manage events" ON public.calendar_events
|
||||
FOR ALL TO authenticated USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = calendar_events.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = calendar_events.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── event_attendees ──
|
||||
CREATE POLICY "Org members can manage event attendees" ON public.event_attendees
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE e.id = event_attendees.event_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── org_google_calendars ──
|
||||
CREATE POLICY "Members can view org calendar" ON public.org_google_calendars
|
||||
FOR SELECT TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members
|
||||
WHERE org_members.org_id = org_google_calendars.org_id AND org_members.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Admins can manage org calendar" ON public.org_google_calendars
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members
|
||||
WHERE org_members.org_id = org_google_calendars.org_id
|
||||
AND org_members.user_id = (select auth.uid())
|
||||
AND org_members.role IN ('admin', 'owner')
|
||||
)
|
||||
);
|
||||
|
||||
-- ── activity_log ──
|
||||
CREATE POLICY "Users can view org activity" ON public.activity_log
|
||||
FOR SELECT TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members m
|
||||
WHERE m.org_id = activity_log.org_id AND m.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Users can insert own activity" ON public.activity_log
|
||||
FOR INSERT TO authenticated WITH CHECK (user_id = (select auth.uid()));
|
||||
|
||||
-- ── user_preferences ──
|
||||
CREATE POLICY "Users can manage own preferences" ON public.user_preferences
|
||||
FOR ALL TO authenticated USING (user_id = (select auth.uid()));
|
||||
|
||||
-- ── matrix_credentials ──
|
||||
CREATE POLICY "Users can read own matrix credentials" ON public.matrix_credentials
|
||||
FOR SELECT TO authenticated USING ((select auth.uid()) = user_id);
|
||||
CREATE POLICY "Users can insert own matrix credentials" ON public.matrix_credentials
|
||||
FOR INSERT TO authenticated WITH CHECK ((select auth.uid()) = user_id);
|
||||
CREATE POLICY "Users can update own matrix credentials" ON public.matrix_credentials
|
||||
FOR UPDATE TO authenticated USING ((select auth.uid()) = user_id);
|
||||
CREATE POLICY "Users can delete own matrix credentials" ON public.matrix_credentials
|
||||
FOR DELETE TO authenticated USING ((select auth.uid()) = user_id);
|
||||
|
||||
-- ── events ──
|
||||
CREATE POLICY "Editors can manage events" ON public.events
|
||||
FOR ALL TO authenticated USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = events.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = events.org_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── event_members ──
|
||||
CREATE POLICY "Editors can manage event members" ON public.event_members
|
||||
FOR ALL TO authenticated USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE e.id = event_members.event_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE e.id = event_members.event_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── event_roles ──
|
||||
CREATE POLICY "Editors can manage event roles" ON public.event_roles
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE e.id = event_roles.event_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── event_departments ──
|
||||
CREATE POLICY "Editors can manage event departments" ON public.event_departments
|
||||
FOR ALL TO authenticated USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE e.id = event_departments.event_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE e.id = event_departments.event_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── event_member_departments ──
|
||||
CREATE POLICY "Editors can manage member departments" ON public.event_member_departments
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.event_members em
|
||||
JOIN public.events e ON em.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE em.id = event_member_departments.event_member_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── event_task_columns ──
|
||||
CREATE POLICY "Editors can manage event task columns" ON public.event_task_columns
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE e.id = event_task_columns.event_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── event_tasks ──
|
||||
CREATE POLICY "Editors can manage event tasks" ON public.event_tasks
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE e.id = event_tasks.event_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── department_dashboards ──
|
||||
CREATE POLICY "Editors can manage department dashboards" ON public.department_dashboards
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = department_dashboards.department_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── dashboard_panels ──
|
||||
CREATE POLICY "Editors can manage dashboard panels" ON public.dashboard_panels
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.department_dashboards dd
|
||||
JOIN public.event_departments ed ON dd.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE dd.id = dashboard_panels.dashboard_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── department_checklists ──
|
||||
CREATE POLICY "Editors can manage department checklists" ON public.department_checklists
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = department_checklists.department_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── department_checklist_items ──
|
||||
CREATE POLICY "Editors can manage dept checklist items" ON public.department_checklist_items
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.department_checklists dc
|
||||
JOIN public.event_departments ed ON dc.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE dc.id = department_checklist_items.checklist_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── department_notes ──
|
||||
CREATE POLICY "Editors can manage department notes" ON public.department_notes
|
||||
FOR ALL TO authenticated USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = department_notes.department_id AND om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- ── schedule_stages ──
|
||||
CREATE POLICY "schedule_stages_select" ON public.schedule_stages
|
||||
FOR SELECT TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = schedule_stages.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "schedule_stages_insert" ON public.schedule_stages
|
||||
FOR INSERT TO authenticated WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = schedule_stages.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "schedule_stages_update" ON public.schedule_stages
|
||||
FOR UPDATE TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = schedule_stages.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "schedule_stages_delete" ON public.schedule_stages
|
||||
FOR DELETE TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = schedule_stages.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
|
||||
-- ── schedule_blocks ──
|
||||
CREATE POLICY "schedule_blocks_select" ON public.schedule_blocks
|
||||
FOR SELECT TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = schedule_blocks.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "schedule_blocks_insert" ON public.schedule_blocks
|
||||
FOR INSERT TO authenticated WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = schedule_blocks.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "schedule_blocks_update" ON public.schedule_blocks
|
||||
FOR UPDATE TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = schedule_blocks.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "schedule_blocks_delete" ON public.schedule_blocks
|
||||
FOR DELETE TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = schedule_blocks.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
|
||||
-- ── department_contacts ──
|
||||
CREATE POLICY "department_contacts_select" ON public.department_contacts
|
||||
FOR SELECT TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_contacts.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "department_contacts_insert" ON public.department_contacts
|
||||
FOR INSERT TO authenticated WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_contacts.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "department_contacts_update" ON public.department_contacts
|
||||
FOR UPDATE TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_contacts.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "department_contacts_delete" ON public.department_contacts
|
||||
FOR DELETE TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_contacts.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
|
||||
-- ── budget_categories ──
|
||||
CREATE POLICY "Editors can manage budget categories" ON public.budget_categories
|
||||
FOR ALL TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = budget_categories.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
|
||||
-- ── budget_items ──
|
||||
CREATE POLICY "Editors can manage budget items" ON public.budget_items
|
||||
FOR ALL TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = budget_items.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
|
||||
-- ── sponsor_tiers ──
|
||||
CREATE POLICY "Editors can manage sponsor tiers" ON public.sponsor_tiers
|
||||
FOR ALL TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = sponsor_tiers.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
|
||||
-- ── sponsors ──
|
||||
CREATE POLICY "Editors can manage sponsors" ON public.sponsors
|
||||
FOR ALL TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = sponsors.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
|
||||
-- ── sponsor_deliverables ──
|
||||
CREATE POLICY "Editors can manage sponsor deliverables" ON public.sponsor_deliverables
|
||||
FOR ALL TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.sponsors s
|
||||
JOIN public.event_departments ed ON s.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE s.id = sponsor_deliverables.sponsor_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
|
||||
-- ── sponsor_allocations ──
|
||||
CREATE POLICY "sponsor_allocations_select" ON public.sponsor_allocations
|
||||
FOR SELECT TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = sponsor_allocations.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "sponsor_allocations_insert" ON public.sponsor_allocations
|
||||
FOR INSERT TO authenticated WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = sponsor_allocations.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "sponsor_allocations_update" ON public.sponsor_allocations
|
||||
FOR UPDATE TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = sponsor_allocations.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "sponsor_allocations_delete" ON public.sponsor_allocations
|
||||
FOR DELETE TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = sponsor_allocations.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
|
||||
-- ── org_contacts ──
|
||||
CREATE POLICY "org_contacts_select" ON public.org_contacts
|
||||
FOR SELECT TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_contacts.org_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "org_contacts_insert" ON public.org_contacts
|
||||
FOR INSERT TO authenticated WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_contacts.org_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "org_contacts_update" ON public.org_contacts
|
||||
FOR UPDATE TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_contacts.org_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "org_contacts_delete" ON public.org_contacts
|
||||
FOR DELETE TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_contacts.org_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
|
||||
-- ── department_pinned_contacts ──
|
||||
CREATE POLICY "dept_pinned_contacts_select" ON public.department_pinned_contacts
|
||||
FOR SELECT TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_pinned_contacts.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "dept_pinned_contacts_insert" ON public.department_pinned_contacts
|
||||
FOR INSERT TO authenticated WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_pinned_contacts.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
CREATE POLICY "dept_pinned_contacts_delete" ON public.department_pinned_contacts
|
||||
FOR DELETE TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
JOIN public.org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_pinned_contacts.department_id AND om.user_id = (select auth.uid()) AND om.role IN ('owner', 'admin', 'editor')
|
||||
));
|
||||
|
||||
-- ── map_layers ──
|
||||
CREATE POLICY "Org members can view map layers" ON public.map_layers
|
||||
FOR SELECT TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = map_layers.department_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can insert map layers" ON public.map_layers
|
||||
FOR INSERT TO authenticated WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = map_layers.department_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can update map layers" ON public.map_layers
|
||||
FOR UPDATE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = map_layers.department_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
))
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = map_layers.department_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can delete map layers" ON public.map_layers
|
||||
FOR DELETE TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ed.id = map_layers.department_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
|
||||
-- ── map_pins ──
|
||||
CREATE POLICY "Org members can view map pins" ON public.map_pins
|
||||
FOR SELECT TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_pins.layer_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can insert map pins" ON public.map_pins
|
||||
FOR INSERT TO authenticated WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_pins.layer_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can update map pins" ON public.map_pins
|
||||
FOR UPDATE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_pins.layer_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
))
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_pins.layer_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can delete map pins" ON public.map_pins
|
||||
FOR DELETE TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_pins.layer_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
|
||||
-- ── map_shapes ──
|
||||
CREATE POLICY "Org members can view map shapes" ON public.map_shapes
|
||||
FOR SELECT TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_shapes.layer_id AND om.user_id = (select auth.uid())
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can insert map shapes" ON public.map_shapes
|
||||
FOR INSERT TO authenticated WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_shapes.layer_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can update map shapes" ON public.map_shapes
|
||||
FOR UPDATE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_shapes.layer_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
))
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_shapes.layer_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
CREATE POLICY "Dept members and editors can delete map shapes" ON public.map_shapes
|
||||
FOR DELETE TO authenticated USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
JOIN public.org_members om ON e.org_id = om.org_id
|
||||
WHERE ml.id = map_shapes.layer_id AND om.user_id = (select auth.uid())
|
||||
AND (om.role IN ('owner', 'admin', 'editor') OR EXISTS (
|
||||
SELECT 1 FROM public.event_member_departments emd
|
||||
JOIN public.event_members em ON emd.event_member_id = em.id
|
||||
WHERE emd.department_id = ed.id AND em.user_id = (select auth.uid())
|
||||
))
|
||||
));
|
||||
25
supabase/migrations/054_test_simple_policy.sql
Normal file
25
supabase/migrations/054_test_simple_policy.sql
Normal file
@@ -0,0 +1,25 @@
|
||||
-- Test: simplest possible policies for organizations + org_members
|
||||
-- Remove is_platform_admin() to isolate the issue
|
||||
|
||||
-- Fix organizations SELECT
|
||||
DROP POLICY IF EXISTS "Members can view their organizations" ON public.organizations;
|
||||
CREATE POLICY "Members can view their organizations" ON public.organizations
|
||||
FOR SELECT TO authenticated
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members
|
||||
WHERE org_id = organizations.id
|
||||
AND user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
-- Fix org_members SELECT - use simplest self-referencing pattern
|
||||
DROP POLICY IF EXISTS "Members can view org members" ON public.org_members;
|
||||
CREATE POLICY "Members can view org members" ON public.org_members
|
||||
FOR SELECT TO authenticated
|
||||
USING (
|
||||
org_id IN (
|
||||
SELECT om.org_id FROM public.org_members om
|
||||
WHERE om.user_id = (select auth.uid())
|
||||
)
|
||||
);
|
||||
67
supabase/migrations/055_fix_org_members_recursion.sql
Normal file
67
supabase/migrations/055_fix_org_members_recursion.sql
Normal file
@@ -0,0 +1,67 @@
|
||||
-- ============================================================
|
||||
-- Migration 055: Fix infinite recursion in org_members SELECT policy
|
||||
-- The previous policy queried org_members from within its own
|
||||
-- SELECT policy, causing PostgreSQL error 42P17.
|
||||
-- Fix: check user_id directly on the current row.
|
||||
-- ============================================================
|
||||
|
||||
DROP POLICY IF EXISTS "Members can view org members" ON public.org_members;
|
||||
|
||||
-- Use auth.uid() directly (not wrapped in select) to avoid PostgreSQL
|
||||
-- detecting infinite recursion on this self-referencing policy.
|
||||
-- This matches the original working pattern from 001_initial_schema.sql.
|
||||
CREATE POLICY "Members can view org members" ON public.org_members
|
||||
FOR SELECT TO authenticated
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_members.org_id
|
||||
AND om.user_id = auth.uid()
|
||||
)
|
||||
);
|
||||
|
||||
-- Also fix the UPDATE and DELETE policies which have the same self-reference
|
||||
DROP POLICY IF EXISTS "Owners and admins can manage members" ON public.org_members;
|
||||
CREATE POLICY "Owners and admins can manage members" ON public.org_members
|
||||
FOR UPDATE TO authenticated
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members om2
|
||||
WHERE om2.org_id = org_members.org_id
|
||||
AND om2.user_id = auth.uid()
|
||||
AND om2.role IN ('owner', 'admin')
|
||||
)
|
||||
)
|
||||
WITH CHECK (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members om2
|
||||
WHERE om2.org_id = org_members.org_id
|
||||
AND om2.user_id = auth.uid()
|
||||
AND om2.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
|
||||
DROP POLICY IF EXISTS "Owners and admins can delete members" ON public.org_members;
|
||||
CREATE POLICY "Owners and admins can delete members" ON public.org_members
|
||||
FOR DELETE TO authenticated
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members om2
|
||||
WHERE om2.org_id = org_members.org_id
|
||||
AND om2.user_id = auth.uid()
|
||||
AND om2.role IN ('owner', 'admin')
|
||||
)
|
||||
);
|
||||
|
||||
DROP POLICY IF EXISTS "Allow member inserts" ON public.org_members;
|
||||
CREATE POLICY "Allow member inserts" ON public.org_members
|
||||
FOR INSERT TO authenticated
|
||||
WITH CHECK (
|
||||
EXISTS (
|
||||
SELECT 1 FROM public.org_members om
|
||||
WHERE om.org_id = org_members.org_id
|
||||
AND om.user_id = auth.uid()
|
||||
AND om.role IN ('owner', 'admin')
|
||||
)
|
||||
OR org_members.user_id = auth.uid()
|
||||
);
|
||||
866
supabase/migrations/056_definitive_rls_fix.sql
Normal file
866
supabase/migrations/056_definitive_rls_fix.sql
Normal file
@@ -0,0 +1,866 @@
|
||||
-- ============================================================
|
||||
-- Migration 056: Definitive RLS fix
|
||||
--
|
||||
-- Root cause: (select auth.uid()) inside a policy that queries
|
||||
-- org_members triggers PostgreSQL 42P17 infinite recursion,
|
||||
-- because org_members' own SELECT policy also queries org_members.
|
||||
--
|
||||
-- Fix (per Supabase docs tip #4 & #5):
|
||||
-- 1. Create SECURITY DEFINER helper functions that bypass RLS
|
||||
-- 2. Use those in all policies — no self-referencing, no recursion
|
||||
-- 3. Wrap function calls in (select ...) for InitPlan caching
|
||||
-- ============================================================
|
||||
|
||||
-- ============================================================
|
||||
-- STEP 1: Create helper functions (SECURITY DEFINER = bypass RLS)
|
||||
-- ============================================================
|
||||
|
||||
-- Returns all org_ids the current user belongs to
|
||||
CREATE OR REPLACE FUNCTION public.get_user_org_ids()
|
||||
RETURNS SETOF uuid
|
||||
LANGUAGE sql
|
||||
STABLE
|
||||
SECURITY DEFINER
|
||||
SET search_path = ''
|
||||
AS $$
|
||||
SELECT org_members.org_id FROM public.org_members WHERE user_id = auth.uid();
|
||||
$$;
|
||||
|
||||
-- Returns the user's role in a specific org (or NULL if not a member)
|
||||
CREATE OR REPLACE FUNCTION public.get_user_org_role(org_id uuid)
|
||||
RETURNS text
|
||||
LANGUAGE sql
|
||||
STABLE
|
||||
SECURITY DEFINER
|
||||
SET search_path = ''
|
||||
AS $$
|
||||
SELECT role FROM public.org_members
|
||||
WHERE org_members.org_id = get_user_org_role.org_id AND user_id = auth.uid()
|
||||
LIMIT 1;
|
||||
$$;
|
||||
|
||||
-- is_org_member already exists from migration 039, just ensure it's correct
|
||||
CREATE OR REPLACE FUNCTION public.is_org_member(org_id uuid)
|
||||
RETURNS boolean
|
||||
LANGUAGE sql
|
||||
STABLE
|
||||
SECURITY DEFINER
|
||||
SET search_path = ''
|
||||
AS $$
|
||||
SELECT EXISTS (
|
||||
SELECT 1 FROM public.org_members
|
||||
WHERE org_members.org_id = is_org_member.org_id
|
||||
AND user_id = auth.uid()
|
||||
);
|
||||
$$;
|
||||
|
||||
-- Returns true if user has editor+ role in the given org
|
||||
CREATE OR REPLACE FUNCTION public.is_org_editor(org_id uuid)
|
||||
RETURNS boolean
|
||||
LANGUAGE sql
|
||||
STABLE
|
||||
SECURITY DEFINER
|
||||
SET search_path = ''
|
||||
AS $$
|
||||
SELECT EXISTS (
|
||||
SELECT 1 FROM public.org_members
|
||||
WHERE org_members.org_id = is_org_editor.org_id
|
||||
AND user_id = auth.uid()
|
||||
AND role IN ('owner', 'admin', 'editor')
|
||||
);
|
||||
$$;
|
||||
|
||||
-- Returns true if user has admin+ role in the given org
|
||||
CREATE OR REPLACE FUNCTION public.is_org_admin(org_id uuid)
|
||||
RETURNS boolean
|
||||
LANGUAGE sql
|
||||
STABLE
|
||||
SECURITY DEFINER
|
||||
SET search_path = ''
|
||||
AS $$
|
||||
SELECT EXISTS (
|
||||
SELECT 1 FROM public.org_members
|
||||
WHERE org_members.org_id = is_org_admin.org_id
|
||||
AND user_id = auth.uid()
|
||||
AND role IN ('owner', 'admin')
|
||||
);
|
||||
$$;
|
||||
|
||||
-- ============================================================
|
||||
-- STEP 2: Drop ALL existing policies on all public tables
|
||||
-- ============================================================
|
||||
DO $$
|
||||
DECLARE
|
||||
r record;
|
||||
BEGIN
|
||||
FOR r IN
|
||||
SELECT schemaname, tablename, policyname
|
||||
FROM pg_policies
|
||||
WHERE schemaname = 'public'
|
||||
LOOP
|
||||
EXECUTE format('DROP POLICY IF EXISTS %I ON %I.%I',
|
||||
r.policyname, r.schemaname, r.tablename);
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
-- ============================================================
|
||||
-- STEP 3: Recreate ALL policies using helper functions
|
||||
-- ============================================================
|
||||
|
||||
-- ── profiles ──
|
||||
CREATE POLICY "Profiles are viewable by everyone" ON public.profiles
|
||||
FOR SELECT TO authenticated USING (true);
|
||||
CREATE POLICY "Users can update own profile" ON public.profiles
|
||||
FOR UPDATE TO authenticated USING ((select auth.uid()) = id);
|
||||
|
||||
-- ── organizations ──
|
||||
CREATE POLICY "Anyone can create organizations" ON public.organizations
|
||||
FOR INSERT TO authenticated WITH CHECK (true);
|
||||
CREATE POLICY "Members can view their organizations" ON public.organizations
|
||||
FOR SELECT TO authenticated
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR (select public.is_org_member(id))
|
||||
);
|
||||
CREATE POLICY "Admins can update organizations" ON public.organizations
|
||||
FOR UPDATE TO authenticated
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR (select public.is_org_admin(id))
|
||||
)
|
||||
WITH CHECK (
|
||||
(select public.is_platform_admin())
|
||||
OR (select public.is_org_admin(id))
|
||||
);
|
||||
CREATE POLICY "Owners can delete organizations" ON public.organizations
|
||||
FOR DELETE TO authenticated
|
||||
USING (
|
||||
(select public.is_platform_admin())
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.org_members
|
||||
WHERE org_id = organizations.id AND user_id = auth.uid() AND role = 'owner'
|
||||
)
|
||||
);
|
||||
|
||||
-- ── org_members ──
|
||||
-- KEY FIX: use get_user_org_ids() to avoid self-referencing recursion
|
||||
CREATE POLICY "Members can view org members" ON public.org_members
|
||||
FOR SELECT TO authenticated
|
||||
USING (org_id IN (select public.get_user_org_ids()));
|
||||
CREATE POLICY "Allow member inserts" ON public.org_members
|
||||
FOR INSERT TO authenticated
|
||||
WITH CHECK (
|
||||
(select public.is_org_admin(org_id))
|
||||
OR org_members.user_id = (select auth.uid())
|
||||
);
|
||||
CREATE POLICY "Admins can update members" ON public.org_members
|
||||
FOR UPDATE TO authenticated
|
||||
USING ((select public.is_org_admin(org_id)))
|
||||
WITH CHECK ((select public.is_org_admin(org_id)));
|
||||
CREATE POLICY "Admins can delete members" ON public.org_members
|
||||
FOR DELETE TO authenticated
|
||||
USING ((select public.is_org_admin(org_id)));
|
||||
|
||||
-- ── org_roles ──
|
||||
CREATE POLICY "Org members can view roles" ON public.org_roles
|
||||
FOR SELECT TO authenticated
|
||||
USING ((select public.is_org_member(org_id)));
|
||||
CREATE POLICY "Admins can manage roles" ON public.org_roles
|
||||
FOR ALL TO authenticated
|
||||
USING ((select public.is_org_admin(org_id)));
|
||||
|
||||
-- ── org_invites ──
|
||||
CREATE POLICY "Anyone can view invite by token" ON public.org_invites
|
||||
FOR SELECT TO anon, authenticated USING (true);
|
||||
CREATE POLICY "Admins can manage invites" ON public.org_invites
|
||||
FOR ALL TO authenticated
|
||||
USING ((select public.is_org_admin(org_id)));
|
||||
|
||||
-- ── documents ──
|
||||
CREATE POLICY "Members can manage documents" ON public.documents
|
||||
FOR ALL TO authenticated
|
||||
USING ((select public.is_org_member(org_id)))
|
||||
WITH CHECK ((select public.is_org_member(org_id)));
|
||||
|
||||
-- ── document_locks ──
|
||||
CREATE POLICY "Org members can view document locks" ON public.document_locks
|
||||
FOR SELECT TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.documents d
|
||||
WHERE d.id = document_locks.document_id
|
||||
AND (select public.is_org_member(d.org_id))
|
||||
));
|
||||
CREATE POLICY "Users can insert their own locks" ON public.document_locks
|
||||
FOR INSERT TO authenticated WITH CHECK (user_id = (select auth.uid()));
|
||||
CREATE POLICY "Users can update their own locks" ON public.document_locks
|
||||
FOR UPDATE TO authenticated USING (user_id = (select auth.uid()));
|
||||
CREATE POLICY "Users can delete locks" ON public.document_locks
|
||||
FOR DELETE TO authenticated
|
||||
USING (user_id = (select auth.uid()) OR last_heartbeat < (now() - interval '2 minutes'));
|
||||
|
||||
-- ── kanban_boards ──
|
||||
CREATE POLICY "Members can manage boards" ON public.kanban_boards
|
||||
FOR ALL TO authenticated
|
||||
USING ((select public.is_org_member(org_id)))
|
||||
WITH CHECK ((select public.is_org_member(org_id)));
|
||||
|
||||
-- ── kanban_columns ──
|
||||
CREATE POLICY "Members can manage columns" ON public.kanban_columns
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.kanban_boards b
|
||||
WHERE b.id = kanban_columns.board_id
|
||||
AND (select public.is_org_member(b.org_id))
|
||||
));
|
||||
|
||||
-- ── kanban_cards ──
|
||||
CREATE POLICY "Members can manage cards" ON public.kanban_cards
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.kanban_columns c
|
||||
JOIN public.kanban_boards b ON c.board_id = b.id
|
||||
WHERE c.id = kanban_cards.column_id
|
||||
AND (select public.is_org_member(b.org_id))
|
||||
));
|
||||
|
||||
-- ── card_assignees ──
|
||||
CREATE POLICY "Card assignees inherit card access" ON public.card_assignees
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards kc
|
||||
JOIN public.kanban_columns kcol ON kcol.id = kc.column_id
|
||||
JOIN public.kanban_boards kb ON kb.id = kcol.board_id
|
||||
WHERE kc.id = card_assignees.card_id
|
||||
AND (select public.is_org_member(kb.org_id))
|
||||
));
|
||||
|
||||
-- ── checklist_items ──
|
||||
CREATE POLICY "Members can manage checklist items" ON public.checklist_items
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards c
|
||||
JOIN public.kanban_columns col ON c.column_id = col.id
|
||||
JOIN public.kanban_boards b ON col.board_id = b.id
|
||||
WHERE c.id = checklist_items.card_id
|
||||
AND (select public.is_org_member(b.org_id))
|
||||
));
|
||||
|
||||
-- ── kanban_checklist_items ──
|
||||
CREATE POLICY "Checklist items inherit card access" ON public.kanban_checklist_items
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards c
|
||||
JOIN public.kanban_columns col ON c.column_id = col.id
|
||||
JOIN public.kanban_boards b ON col.board_id = b.id
|
||||
WHERE c.id = kanban_checklist_items.card_id
|
||||
AND (select public.is_org_member(b.org_id))
|
||||
));
|
||||
|
||||
-- ── kanban_comments ──
|
||||
CREATE POLICY "Comments inherit card access" ON public.kanban_comments
|
||||
FOR SELECT TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards c
|
||||
JOIN public.kanban_columns col ON c.column_id = col.id
|
||||
JOIN public.kanban_boards b ON col.board_id = b.id
|
||||
WHERE c.id = kanban_comments.card_id
|
||||
AND (select public.is_org_member(b.org_id))
|
||||
));
|
||||
CREATE POLICY "Users can insert own comments" ON public.kanban_comments
|
||||
FOR INSERT TO authenticated
|
||||
WITH CHECK (
|
||||
user_id = (select auth.uid())
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards c
|
||||
JOIN public.kanban_columns col ON c.column_id = col.id
|
||||
JOIN public.kanban_boards b ON col.board_id = b.id
|
||||
WHERE c.id = kanban_comments.card_id
|
||||
AND (select public.is_org_member(b.org_id))
|
||||
)
|
||||
);
|
||||
CREATE POLICY "Users can update own comments" ON public.kanban_comments
|
||||
FOR UPDATE TO authenticated USING (user_id = (select auth.uid()));
|
||||
CREATE POLICY "Users can delete own comments" ON public.kanban_comments
|
||||
FOR DELETE TO authenticated USING (user_id = (select auth.uid()));
|
||||
|
||||
-- ── kanban_labels ──
|
||||
CREATE POLICY "Labels accessible to org members" ON public.kanban_labels
|
||||
FOR ALL TO authenticated
|
||||
USING ((select public.is_org_member(org_id)));
|
||||
|
||||
-- ── card_labels ──
|
||||
CREATE POLICY "Card labels inherit card access" ON public.card_labels
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.kanban_cards c
|
||||
JOIN public.kanban_columns col ON c.column_id = col.id
|
||||
JOIN public.kanban_boards b ON col.board_id = b.id
|
||||
WHERE c.id = card_labels.card_id
|
||||
AND (select public.is_org_member(b.org_id))
|
||||
));
|
||||
|
||||
-- ── tags ──
|
||||
CREATE POLICY "Users can view tags in their orgs" ON public.tags
|
||||
FOR SELECT TO authenticated
|
||||
USING (org_id IN (select public.get_user_org_ids()));
|
||||
CREATE POLICY "Admins can manage tags" ON public.tags
|
||||
FOR ALL TO authenticated
|
||||
USING ((select public.is_org_admin(org_id)));
|
||||
|
||||
-- ── card_tags ──
|
||||
CREATE POLICY "Members can manage card tags" ON public.card_tags
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.tags t
|
||||
WHERE t.id = card_tags.tag_id
|
||||
AND (select public.is_org_member(t.org_id))
|
||||
));
|
||||
|
||||
-- ── teams ──
|
||||
CREATE POLICY "Users can view teams in their orgs" ON public.teams
|
||||
FOR SELECT TO authenticated
|
||||
USING (org_id IN (select public.get_user_org_ids()));
|
||||
CREATE POLICY "Admins can manage teams" ON public.teams
|
||||
FOR ALL TO authenticated
|
||||
USING ((select public.is_org_admin(org_id)));
|
||||
|
||||
-- ── team_members ──
|
||||
CREATE POLICY "Users can view team members" ON public.team_members
|
||||
FOR SELECT TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.teams t
|
||||
WHERE t.id = team_members.team_id
|
||||
AND (select public.is_org_member(t.org_id))
|
||||
));
|
||||
CREATE POLICY "Admins can manage team members" ON public.team_members
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.teams t
|
||||
WHERE t.id = team_members.team_id
|
||||
AND (select public.is_org_admin(t.org_id))
|
||||
));
|
||||
|
||||
-- ── calendar_events ──
|
||||
CREATE POLICY "Members can manage calendar events" ON public.calendar_events
|
||||
FOR ALL TO authenticated
|
||||
USING ((select public.is_org_member(org_id)))
|
||||
WITH CHECK ((select public.is_org_member(org_id)));
|
||||
|
||||
-- ── event_attendees ──
|
||||
CREATE POLICY "Members can manage event attendees" ON public.event_attendees
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
WHERE e.id = event_attendees.event_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── org_google_calendars ──
|
||||
CREATE POLICY "Members can view org calendar" ON public.org_google_calendars
|
||||
FOR SELECT TO authenticated
|
||||
USING ((select public.is_org_member(org_id)));
|
||||
CREATE POLICY "Admins can manage org calendar" ON public.org_google_calendars
|
||||
FOR ALL TO authenticated
|
||||
USING ((select public.is_org_admin(org_id)));
|
||||
|
||||
-- ── activity_log ──
|
||||
CREATE POLICY "Users can view org activity" ON public.activity_log
|
||||
FOR SELECT TO authenticated
|
||||
USING ((select public.is_org_member(org_id)));
|
||||
CREATE POLICY "Users can insert own activity" ON public.activity_log
|
||||
FOR INSERT TO authenticated WITH CHECK (user_id = (select auth.uid()));
|
||||
|
||||
-- ── user_preferences ──
|
||||
CREATE POLICY "Users can manage own preferences" ON public.user_preferences
|
||||
FOR ALL TO authenticated USING (user_id = (select auth.uid()));
|
||||
|
||||
-- ── matrix_credentials ──
|
||||
CREATE POLICY "Users can read own matrix credentials" ON public.matrix_credentials
|
||||
FOR SELECT TO authenticated USING ((select auth.uid()) = user_id);
|
||||
CREATE POLICY "Users can insert own matrix credentials" ON public.matrix_credentials
|
||||
FOR INSERT TO authenticated WITH CHECK ((select auth.uid()) = user_id);
|
||||
CREATE POLICY "Users can update own matrix credentials" ON public.matrix_credentials
|
||||
FOR UPDATE TO authenticated USING ((select auth.uid()) = user_id);
|
||||
CREATE POLICY "Users can delete own matrix credentials" ON public.matrix_credentials
|
||||
FOR DELETE TO authenticated USING ((select auth.uid()) = user_id);
|
||||
|
||||
-- ── events ──
|
||||
CREATE POLICY "Members can manage events" ON public.events
|
||||
FOR ALL TO authenticated
|
||||
USING ((select public.is_org_member(org_id)))
|
||||
WITH CHECK ((select public.is_org_member(org_id)));
|
||||
|
||||
-- ── event_members ──
|
||||
CREATE POLICY "Members can manage event members" ON public.event_members
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
WHERE e.id = event_members.event_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
))
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
WHERE e.id = event_members.event_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── event_roles ──
|
||||
CREATE POLICY "Members can manage event roles" ON public.event_roles
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
WHERE e.id = event_roles.event_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── event_departments ──
|
||||
CREATE POLICY "Members can manage event departments" ON public.event_departments
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
WHERE e.id = event_departments.event_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
))
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
WHERE e.id = event_departments.event_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── event_member_departments ──
|
||||
CREATE POLICY "Members can manage member departments" ON public.event_member_departments
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_members em
|
||||
JOIN public.events e ON em.event_id = e.id
|
||||
WHERE em.id = event_member_departments.event_member_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── event_task_columns ──
|
||||
CREATE POLICY "Members can manage event task columns" ON public.event_task_columns
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
WHERE e.id = event_task_columns.event_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── event_tasks ──
|
||||
CREATE POLICY "Members can manage event tasks" ON public.event_tasks
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.events e
|
||||
WHERE e.id = event_tasks.event_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── department_dashboards ──
|
||||
CREATE POLICY "Members can manage department dashboards" ON public.department_dashboards
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ed.id = department_dashboards.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── dashboard_panels ──
|
||||
CREATE POLICY "Members can manage dashboard panels" ON public.dashboard_panels
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.department_dashboards dd
|
||||
JOIN public.event_departments ed ON dd.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE dd.id = dashboard_panels.dashboard_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── department_checklists ──
|
||||
CREATE POLICY "Members can manage department checklists" ON public.department_checklists
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ed.id = department_checklists.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── department_checklist_items ──
|
||||
CREATE POLICY "Members can manage dept checklist items" ON public.department_checklist_items
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.department_checklists dc
|
||||
JOIN public.event_departments ed ON dc.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE dc.id = department_checklist_items.checklist_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── department_notes ──
|
||||
CREATE POLICY "Members can manage department notes" ON public.department_notes
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ed.id = department_notes.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── schedule_stages ──
|
||||
CREATE POLICY "schedule_stages_select" ON public.schedule_stages
|
||||
FOR SELECT TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = schedule_stages.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
CREATE POLICY "schedule_stages_insert" ON public.schedule_stages
|
||||
FOR INSERT TO authenticated
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = schedule_stages.department_id
|
||||
AND (select public.is_org_editor(e.org_id))
|
||||
));
|
||||
CREATE POLICY "schedule_stages_update" ON public.schedule_stages
|
||||
FOR UPDATE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = schedule_stages.department_id
|
||||
AND (select public.is_org_editor(e.org_id))
|
||||
));
|
||||
CREATE POLICY "schedule_stages_delete" ON public.schedule_stages
|
||||
FOR DELETE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = schedule_stages.department_id
|
||||
AND (select public.is_org_editor(e.org_id))
|
||||
));
|
||||
|
||||
-- ── schedule_blocks ──
|
||||
CREATE POLICY "schedule_blocks_select" ON public.schedule_blocks
|
||||
FOR SELECT TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = schedule_blocks.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
CREATE POLICY "schedule_blocks_insert" ON public.schedule_blocks
|
||||
FOR INSERT TO authenticated
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = schedule_blocks.department_id
|
||||
AND (select public.is_org_editor(e.org_id))
|
||||
));
|
||||
CREATE POLICY "schedule_blocks_update" ON public.schedule_blocks
|
||||
FOR UPDATE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = schedule_blocks.department_id
|
||||
AND (select public.is_org_editor(e.org_id))
|
||||
));
|
||||
CREATE POLICY "schedule_blocks_delete" ON public.schedule_blocks
|
||||
FOR DELETE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = schedule_blocks.department_id
|
||||
AND (select public.is_org_editor(e.org_id))
|
||||
));
|
||||
|
||||
-- ── department_contacts ──
|
||||
CREATE POLICY "department_contacts_select" ON public.department_contacts
|
||||
FOR SELECT TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = department_contacts.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
CREATE POLICY "department_contacts_insert" ON public.department_contacts
|
||||
FOR INSERT TO authenticated
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = department_contacts.department_id
|
||||
AND (select public.is_org_editor(e.org_id))
|
||||
));
|
||||
CREATE POLICY "department_contacts_update" ON public.department_contacts
|
||||
FOR UPDATE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = department_contacts.department_id
|
||||
AND (select public.is_org_editor(e.org_id))
|
||||
));
|
||||
CREATE POLICY "department_contacts_delete" ON public.department_contacts
|
||||
FOR DELETE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = department_contacts.department_id
|
||||
AND (select public.is_org_editor(e.org_id))
|
||||
));
|
||||
|
||||
-- ── budget_categories ──
|
||||
CREATE POLICY "Members can manage budget categories" ON public.budget_categories
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ed.id = budget_categories.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── budget_items ──
|
||||
CREATE POLICY "Members can manage budget items" ON public.budget_items
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ed.id = budget_items.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── sponsor_tiers ──
|
||||
CREATE POLICY "Members can manage sponsor tiers" ON public.sponsor_tiers
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ed.id = sponsor_tiers.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── sponsors ──
|
||||
CREATE POLICY "Members can manage sponsors" ON public.sponsors
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ed.id = sponsors.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── sponsor_deliverables ──
|
||||
CREATE POLICY "Members can manage sponsor deliverables" ON public.sponsor_deliverables
|
||||
FOR ALL TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.sponsors s
|
||||
JOIN public.event_departments ed ON s.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE s.id = sponsor_deliverables.sponsor_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── sponsor_allocations ──
|
||||
CREATE POLICY "sponsor_allocations_select" ON public.sponsor_allocations
|
||||
FOR SELECT TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = sponsor_allocations.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
CREATE POLICY "sponsor_allocations_insert" ON public.sponsor_allocations
|
||||
FOR INSERT TO authenticated
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = sponsor_allocations.department_id
|
||||
AND (select public.is_org_editor(e.org_id))
|
||||
));
|
||||
CREATE POLICY "sponsor_allocations_update" ON public.sponsor_allocations
|
||||
FOR UPDATE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = sponsor_allocations.department_id
|
||||
AND (select public.is_org_editor(e.org_id))
|
||||
));
|
||||
CREATE POLICY "sponsor_allocations_delete" ON public.sponsor_allocations
|
||||
FOR DELETE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = sponsor_allocations.department_id
|
||||
AND (select public.is_org_editor(e.org_id))
|
||||
));
|
||||
|
||||
-- ── org_contacts ──
|
||||
CREATE POLICY "org_contacts_select" ON public.org_contacts
|
||||
FOR SELECT TO authenticated
|
||||
USING ((select public.is_org_member(org_id)));
|
||||
CREATE POLICY "org_contacts_insert" ON public.org_contacts
|
||||
FOR INSERT TO authenticated
|
||||
WITH CHECK ((select public.is_org_editor(org_id)));
|
||||
CREATE POLICY "org_contacts_update" ON public.org_contacts
|
||||
FOR UPDATE TO authenticated
|
||||
USING ((select public.is_org_editor(org_id)));
|
||||
CREATE POLICY "org_contacts_delete" ON public.org_contacts
|
||||
FOR DELETE TO authenticated
|
||||
USING ((select public.is_org_editor(org_id)));
|
||||
|
||||
-- ── department_pinned_contacts ──
|
||||
CREATE POLICY "dept_pinned_contacts_select" ON public.department_pinned_contacts
|
||||
FOR SELECT TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = department_pinned_contacts.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
CREATE POLICY "dept_pinned_contacts_insert" ON public.department_pinned_contacts
|
||||
FOR INSERT TO authenticated
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = department_pinned_contacts.department_id
|
||||
AND (select public.is_org_editor(e.org_id))
|
||||
));
|
||||
CREATE POLICY "dept_pinned_contacts_delete" ON public.department_pinned_contacts
|
||||
FOR DELETE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON e.id = ed.event_id
|
||||
WHERE ed.id = department_pinned_contacts.department_id
|
||||
AND (select public.is_org_editor(e.org_id))
|
||||
));
|
||||
|
||||
-- ── map_layers ──
|
||||
CREATE POLICY "Org members can view map layers" ON public.map_layers
|
||||
FOR SELECT TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ed.id = map_layers.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
CREATE POLICY "Editors can insert map layers" ON public.map_layers
|
||||
FOR INSERT TO authenticated
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ed.id = map_layers.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
CREATE POLICY "Editors can update map layers" ON public.map_layers
|
||||
FOR UPDATE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ed.id = map_layers.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
))
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ed.id = map_layers.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
CREATE POLICY "Editors can delete map layers" ON public.map_layers
|
||||
FOR DELETE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.event_departments ed
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ed.id = map_layers.department_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── map_pins ──
|
||||
CREATE POLICY "Org members can view map pins" ON public.map_pins
|
||||
FOR SELECT TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ml.id = map_pins.layer_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
CREATE POLICY "Editors can insert map pins" ON public.map_pins
|
||||
FOR INSERT TO authenticated
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ml.id = map_pins.layer_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
CREATE POLICY "Editors can update map pins" ON public.map_pins
|
||||
FOR UPDATE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ml.id = map_pins.layer_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
))
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ml.id = map_pins.layer_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
CREATE POLICY "Editors can delete map pins" ON public.map_pins
|
||||
FOR DELETE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ml.id = map_pins.layer_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
|
||||
-- ── map_shapes ──
|
||||
CREATE POLICY "Org members can view map shapes" ON public.map_shapes
|
||||
FOR SELECT TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ml.id = map_shapes.layer_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
CREATE POLICY "Editors can insert map shapes" ON public.map_shapes
|
||||
FOR INSERT TO authenticated
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ml.id = map_shapes.layer_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
CREATE POLICY "Editors can update map shapes" ON public.map_shapes
|
||||
FOR UPDATE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ml.id = map_shapes.layer_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
))
|
||||
WITH CHECK (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ml.id = map_shapes.layer_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
CREATE POLICY "Editors can delete map shapes" ON public.map_shapes
|
||||
FOR DELETE TO authenticated
|
||||
USING (EXISTS (
|
||||
SELECT 1 FROM public.map_layers ml
|
||||
JOIN public.event_departments ed ON ml.department_id = ed.id
|
||||
JOIN public.events e ON ed.event_id = e.id
|
||||
WHERE ml.id = map_shapes.layer_id
|
||||
AND (select public.is_org_member(e.org_id))
|
||||
));
|
||||
Reference in New Issue
Block a user