From 97c4b9db5b80f178968ed410c195401bde8b08e8 Mon Sep 17 00:00:00 2001 From: Julien Nahum Date: Tue, 22 Oct 2024 11:04:49 +0200 Subject: [PATCH] Fix mentions in front-end + email spam --- .../Forms/FormEmailNotification.php | 19 ++++++++++++++----- client/composables/useParseMention.js | 4 ++-- client/lib/quill/quillMentionExtension.js | 4 ++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/api/app/Notifications/Forms/FormEmailNotification.php b/api/app/Notifications/Forms/FormEmailNotification.php index 529aae8f..da127de6 100644 --- a/api/app/Notifications/Forms/FormEmailNotification.php +++ b/api/app/Notifications/Forms/FormEmailNotification.php @@ -127,14 +127,23 @@ private function addCustomHeaders(Email $message): void $formId = $this->event->form->id; $submissionId = $this->event->data['submission_id'] ?? 'unknown'; $domain = Str::after(config('app.url'), '://'); + $timestamp = time(); - $uniquePart = substr(md5($formId . $submissionId), 0, 8); - $messageId = "form-{$formId}-{$uniquePart}@{$domain}"; - $references = "form-{$formId}@{$domain}"; + // Create a unique Message-ID for each submission + $messageId = ""; - $message->getHeaders()->remove('Message-ID'); - $message->getHeaders()->addIdHeader('Message-ID', $messageId); + // Create a References header that links to the form, but not to specific submissions + $references = ""; + + // Add our custom Message-ID as X-Custom-Message-ID + $message->getHeaders()->addTextHeader('X-Custom-Message-ID', $messageId); + + // Add References header $message->getHeaders()->addTextHeader('References', $references); + + // Add a unique Thread-Index to further prevent grouping + $threadIndex = base64_encode(pack('H*', md5($formId . $submissionId . $timestamp))); + $message->getHeaders()->addTextHeader('Thread-Index', $threadIndex); } private function getMailData(): array diff --git a/client/composables/useParseMention.js b/client/composables/useParseMention.js index 59494d30..1d11d953 100644 --- a/client/composables/useParseMention.js +++ b/client/composables/useParseMention.js @@ -14,7 +14,7 @@ export function useParseMention(content, mentionsAllowed, form, formData) { const doc = parser.parseFromString(content, 'text/html') // Find all elements with mention attribute - const mentionElements = doc.querySelectorAll('[mention]') + const mentionElements = doc.querySelectorAll('[mention], [mention=""]') mentionElements.forEach(element => { const fieldId = element.getAttribute('mention-field-id') @@ -36,4 +36,4 @@ export function useParseMention(content, mentionsAllowed, form, formData) { // Return the processed HTML content return doc.body.innerHTML -} \ No newline at end of file +} diff --git a/client/lib/quill/quillMentionExtension.js b/client/lib/quill/quillMentionExtension.js index ffb28d8d..49442ab7 100644 --- a/client/lib/quill/quillMentionExtension.js +++ b/client/lib/quill/quillMentionExtension.js @@ -18,7 +18,7 @@ export default function registerMentionExtension(Quill) { node.setAttribute('mention', 'true') if (data && typeof data === 'object') { - node.setAttribute('mention-field-id', data.field?.nf_id || '') + node.setAttribute('mention-field-id', data.field?.id || '') node.setAttribute('mention-field-name', data.field?.name || '') node.setAttribute('mention-fallback', data.fallback || '') node.textContent = data.field?.name || '' @@ -53,7 +53,7 @@ export default function registerMentionExtension(Quill) { static value(domNode) { return { field: { - nf_id: domNode.getAttribute('mention-field-id') || '', + id: domNode.getAttribute('mention-field-id') || '', name: domNode.getAttribute('mention-field-name') || '' }, fallback: domNode.getAttribute('mention-fallback') || ''