-- ============================================================================= -- Migration: 20260419000015_communication_security_hardening -- Sessão 6 — revisão Comunicação. Resolve V#1-V#5 (2 críticos + 3 altos). -- V#6-V#10 adiados (médios/baixos com plano completo no DB). -- -- 🔴 V#1+V#2 são bugs P0: policies usavam (tenant_id = auth.uid()) — comparação -- de UUID de tenant com UUID de user. Tabelas inacessíveis na prática. -- ============================================================================= -- ───────────────────────────────────────────────────────────────────────── -- V#1: email_layout_config — fix BUG do tenant_id = auth.uid() -- ----------------------------------------------------------------------------- DROP POLICY IF EXISTS "tenant owns email layout config" ON public.email_layout_config; DROP POLICY IF EXISTS "email_layout_config: tenant_admin all" ON public.email_layout_config; CREATE POLICY "email_layout_config: tenant_admin all" ON public.email_layout_config FOR ALL TO authenticated USING ( public.is_saas_admin() OR tenant_id IN ( SELECT tm.tenant_id FROM public.tenant_members tm WHERE tm.user_id = auth.uid() AND tm.status = 'active' AND tm.role IN ('tenant_admin','admin','owner') ) ) WITH CHECK ( public.is_saas_admin() OR tenant_id IN ( SELECT tm.tenant_id FROM public.tenant_members tm WHERE tm.user_id = auth.uid() AND tm.status = 'active' AND tm.role IN ('tenant_admin','admin','owner') ) ); -- ───────────────────────────────────────────────────────────────────────── -- V#2: email_templates_tenant — MESMO bug -- ----------------------------------------------------------------------------- DROP POLICY IF EXISTS "tenant manages own overrides" ON public.email_templates_tenant; DROP POLICY IF EXISTS "email_templates_tenant: tenant_admin all" ON public.email_templates_tenant; CREATE POLICY "email_templates_tenant: tenant_admin all" ON public.email_templates_tenant FOR ALL TO authenticated USING ( public.is_saas_admin() OR tenant_id IN ( SELECT tm.tenant_id FROM public.tenant_members tm WHERE tm.user_id = auth.uid() AND tm.status = 'active' AND tm.role IN ('tenant_admin','admin','owner') ) ) WITH CHECK ( public.is_saas_admin() OR tenant_id IN ( SELECT tm.tenant_id FROM public.tenant_members tm WHERE tm.user_id = auth.uid() AND tm.status = 'active' AND tm.role IN ('tenant_admin','admin','owner') ) ); -- ───────────────────────────────────────────────────────────────────────── -- V#3: notification_logs — SELECT pra tenant_member -- ----------------------------------------------------------------------------- DROP POLICY IF EXISTS "notif_logs_tenant_member" ON public.notification_logs; CREATE POLICY "notif_logs_tenant_member" ON public.notification_logs FOR SELECT TO authenticated USING ( public.is_saas_admin() OR tenant_id IN ( SELECT tm.tenant_id FROM public.tenant_members tm WHERE tm.user_id = auth.uid() AND tm.status = 'active' ) ); -- ───────────────────────────────────────────────────────────────────────── -- V#4: notification_queue — SELECT pra tenant_member -- ----------------------------------------------------------------------------- DROP POLICY IF EXISTS "notif_queue_tenant_member" ON public.notification_queue; CREATE POLICY "notif_queue_tenant_member" ON public.notification_queue FOR SELECT TO authenticated USING ( public.is_saas_admin() OR tenant_id IN ( SELECT tm.tenant_id FROM public.tenant_members tm WHERE tm.user_id = auth.uid() AND tm.status = 'active' ) ); -- ───────────────────────────────────────────────────────────────────────── -- V#5: notification_channels — SELECT pra tenant_member; INSERT tenant_admin; UPDATE/DELETE owner -- ----------------------------------------------------------------------------- DROP POLICY IF EXISTS "notification_channels_owner" ON public.notification_channels; DROP POLICY IF EXISTS "notif_channels_select" ON public.notification_channels; DROP POLICY IF EXISTS "notif_channels_insert" ON public.notification_channels; DROP POLICY IF EXISTS "notif_channels_modify" ON public.notification_channels; CREATE POLICY "notif_channels_select" ON public.notification_channels FOR SELECT TO authenticated USING ( deleted_at IS NULL AND ( public.is_saas_admin() OR owner_id = auth.uid() OR tenant_id IN ( SELECT tm.tenant_id FROM public.tenant_members tm WHERE tm.user_id = auth.uid() AND tm.status = 'active' ) ) ); CREATE POLICY "notif_channels_insert" ON public.notification_channels FOR INSERT TO authenticated WITH CHECK ( owner_id = auth.uid() AND tenant_id IN ( SELECT tm.tenant_id FROM public.tenant_members tm WHERE tm.user_id = auth.uid() AND tm.status = 'active' ) ); CREATE POLICY "notif_channels_modify" ON public.notification_channels FOR UPDATE TO authenticated USING (owner_id = auth.uid() OR public.is_saas_admin()) WITH CHECK (owner_id = auth.uid() OR public.is_saas_admin()); CREATE POLICY "notif_channels_delete" ON public.notification_channels FOR DELETE TO authenticated USING (owner_id = auth.uid() OR public.is_saas_admin());