notifications(P4d): form submission submitter + admin alerts
submitForm now enqueues two kinds of notifications, gated per the design:
- form_submission_received: ONLY when the submitter is authenticated
(members or public_auth visibility). Recipient is the verified auth
email (user.email), never the typed body.email. Anonymous public
submissions skip the confirmation because confirming to a typed
address is a victim-spam vector.
- form_submission_admin: one row per member who holds forms.manage in
the space (mirrors the forms-guard / forms RLS gate). Dedupe by
(submission, admin) so a replay is a no-op.
Finding all permission holders without N round-trips needs a new SQL
helper. Migration 047 adds members_with_permission(sid, perm): the
inverted, set-returning form of user_has_permission, with the same
current/late status gate (046) and the same admin shortcut +
space_role_permissions / user_effective_roles fallback. Additive,
introduces no new tables or policies; existing callers unchanged.
Mirrored into schema.sql; types/database.ts updated.
renderFormEmail + formDedupeKey live in notifications-logic; 6 new
render/dedupe unit tests cover both types, fallback labels, escaping.
Suite 565, build clean.
This commit is contained in:
@@ -1769,6 +1769,29 @@ AS $$
|
||||
);
|
||||
$$;
|
||||
|
||||
-- Inverted, set-returning form of user_has_permission: which members in this
|
||||
-- space hold the named permission? Same membership-status gate (current/late,
|
||||
-- mirrors 046), same admin-shortcut, same space_role_permissions +
|
||||
-- user_effective_roles fallback. Used by notification fan-outs (e.g. the
|
||||
-- forms.manage admin alert) where N user_has_permission calls would be N
|
||||
-- round-trips. Equivalent to scripts/047_members_with_permission.sql.
|
||||
CREATE OR REPLACE FUNCTION public.members_with_permission(sid uuid, perm text)
|
||||
RETURNS TABLE(member_id uuid) LANGUAGE sql STABLE SECURITY DEFINER SET search_path = public
|
||||
AS $$
|
||||
SELECT sm.id
|
||||
FROM public.space_members sm
|
||||
WHERE sm.space_id = sid
|
||||
AND sm.status IN ('current','late')
|
||||
AND (
|
||||
sm.role = 'admin'
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM public.space_role_permissions p
|
||||
WHERE p.space_id = sid AND p.permission = perm
|
||||
AND p.subject IN (SELECT public.user_effective_roles(sm.user_id, sid))
|
||||
)
|
||||
);
|
||||
$$;
|
||||
|
||||
ALTER TABLE public.space_role_permissions ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE public.ops_acl ENABLE ROW LEVEL SECURITY;
|
||||
DROP POLICY IF EXISTS role_perms_select ON public.space_role_permissions;
|
||||
|
||||
Reference in New Issue
Block a user