From 460c5c87ffcd6944312002fb326e1460a0437c5a Mon Sep 17 00:00:00 2001 From: titanism <101466223+titanism@users.noreply.github.com> Date: Wed, 4 Sep 2024 13:23:40 -0500 Subject: [PATCH] fix: fixed caldav issue, MX rewrite WIP --- caldav-server.js | 76 +++++++++++++++++++++++-------------------- helpers/on-data-mx.js | 29 +++++++++++++++++ 2 files changed, 69 insertions(+), 36 deletions(-) diff --git a/caldav-server.js b/caldav-server.js index deb85219b8..b916df70bf 100644 --- a/caldav-server.js +++ b/caldav-server.js @@ -592,10 +592,10 @@ class CalDAV extends API { // if (!oldEvent) throw new TypeError('old vevent missing'); - oldEvent.updatePropertyWithValue('status', 'CANCELLED'); + const attendees = oldEvent.getAllProperties('attendee'); - if (oldEvent.attendees.length > 0) { - for (const attendee of oldEvent.attendees) { + if (attendees.length > 0) { + for (const attendee of attendees) { let oldEmail = attendee.getFirstValue(); if (!oldEmail || !/^mailto:/i.test(oldEmail)) { // fallback to EMAIL param @@ -604,17 +604,19 @@ class CalDAV extends API { if (!oldEmail) continue; oldEmail = oldEmail.replace('mailto:', '').toLowerCase().trim(); - const match = event.attendees.find((attendee) => { - let address = attendee.getFirstValue(); - if (!address || !/^mailto:/i.test(address)) { - // fallback to EMAIL param - address = attendee.getParameter('email'); - } + const match = event.attendees + ? event.attendees.find((attendee) => { + let address = attendee.getFirstValue(); + if (!address || !/^mailto:/i.test(address)) { + // fallback to EMAIL param + address = attendee.getParameter('email'); + } - if (!address) return; - address = address.replace('mailto:', '').toLowerCase().trim(); - return address === oldEmail; - }); + if (!address) return; + address = address.replace('mailto:', '').toLowerCase().trim(); + return address === oldEmail; + }) + : null; // if there was a match found then that means the user wasn't removed if (match) continue; @@ -681,34 +683,36 @@ class CalDAV extends API { .replace('mailto:', '') .trim() .toLowerCase(); - for (const attendee of event.attendees) { - // TODO: if SCHEDULE-AGENT=CLIENT then do not send invite (?) - // const scheduleAgent = attendee.getParameter('schedule-agent'); - // if (scheduleAgent && scheduleAgent.toLowerCase() === 'client') continue; - - // skip attendees that were already DECLINED - const partStat = attendee.getParameter('partstat'); - if (partStat && partStat.toLowerCase() === 'declined') continue; - - let email = attendee.getFirstValue(); - if (!email || !email.startsWith('mailto:')) { - // fallback to EMAIL param - email = attendee.getParameter('email'); - } + if (event.attendees) { + for (const attendee of event.attendees) { + // TODO: if SCHEDULE-AGENT=CLIENT then do not send invite (?) + // const scheduleAgent = attendee.getParameter('schedule-agent'); + // if (scheduleAgent && scheduleAgent.toLowerCase() === 'client') continue; + + // skip attendees that were already DECLINED + const partStat = attendee.getParameter('partstat'); + if (partStat && partStat.toLowerCase() === 'declined') continue; + + let email = attendee.getFirstValue(); + if (!email || !email.startsWith('mailto:')) { + // fallback to EMAIL param + email = attendee.getParameter('email'); + } - if (!email) continue; + if (!email) continue; - email = email.replace('mailto:', '').toLowerCase().trim(); + email = email.replace('mailto:', '').toLowerCase().trim(); - if (!isEmail(email)) continue; + if (!isEmail(email)) continue; - if (email === organizerEmail) continue; + if (email === organizerEmail) continue; - const commonName = attendee.getParameter('cn'); - if (commonName) { - to.push(`"${commonName}" <${email}>`); - } else { - to.push(email); + const commonName = attendee.getParameter('cn'); + if (commonName) { + to.push(`"${commonName}" <${email}>`); + } else { + to.push(email); + } } } diff --git a/helpers/on-data-mx.js b/helpers/on-data-mx.js index 9022958924..3f2a9e7978 100644 --- a/helpers/on-data-mx.js +++ b/helpers/on-data-mx.js @@ -9,6 +9,7 @@ const SpamScanner = require('spamscanner'); const _ = require('lodash'); const bytes = require('@forwardemail/bytes'); const isSANB = require('is-string-and-not-blank'); +const pMap = require('p-map'); const { SRS } = require('sender-rewriting-scheme'); const { isEmail } = require('validator'); const { sealMessage } = require('mailauth'); @@ -48,6 +49,16 @@ const scanner = new SpamScanner({ } }); +async function imap(aliases) { + console.log('aliases', aliases); + // TODO: finish this +} + +async function forward(recipient) { + console.log('recipient', recipient); + // TODO: finish this +} + // // TODO: all counters should be reflected in new deliverability dashboard for users // @@ -278,8 +289,26 @@ async function onDataMX(raw, session, headers, body) { ) return; + // TODO: we need to check denylist for each in between deliveries + console.log('WIP'); + // deliver to IMAP and forward messages in parallel + const [imapBounces, forwardBounces] = await Promise.all([ + // imap + data.imap.length === 0 ? Promise.resolve() : imap(data.imap), + // forwarding + data.normalized.length === 0 + ? Promise.resolve() + : pMap(data.normalized, (recipient) => forward(recipient), { + concurrency: config.concurrency + }) + ]); + + const bounces = [...imapBounces, ...forwardBounces]; + + console.log('bounces', bounces); + // TODO: log here // logger.info('email delivery attempt', { // session,