From e258472391b7f91b07a916b7edb6ecc5e5c3c048 Mon Sep 17 00:00:00 2001 From: Luca <102960244+Luca-Timo@users.noreply.github.com> Date: Fri, 12 Jun 2026 14:54:18 +0200 Subject: [PATCH] fix(email): guard round-trip test when IMAP username isn't an email MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The round-trip recipient is imap_user (not hardcoded). Some hosts use a non-email IMAP login — guard against silently sending to a bogus address: return a clear 'recipient_not_email' error explaining to use a mailbox whose username is its email, or test connection + manual send instead. --- backend/src/routes/adminEmail.js | 1 + backend/src/services/emailIntakeService.js | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/src/routes/adminEmail.js b/backend/src/routes/adminEmail.js index 5683c62b..92173823 100644 --- a/backend/src/routes/adminEmail.js +++ b/backend/src/routes/adminEmail.js @@ -232,6 +232,7 @@ router.post('/incoming-config/roundtrip', adminAuth, requirePermission('email.se const map = { smtp_unconfigured: 'Configure and save the outgoing SMTP settings first.', imap_unconfigured: 'Configure and save the incoming IMAP settings first.', + recipient_not_email: `The IMAP username (“${result.recipient || ''}”) isn’t an email address, so the round-trip test can’t auto-address itself. Use a mailbox whose username is its email, or send a test email there manually and use “Test connection”.`, send_failed: `Could not send the test email${result.error ? `: ${result.error}` : ''}.`, not_received: 'The email was sent but did not arrive within 30s — possible delivery delay/greylisting. Check the Received emails tab in a moment.', }; diff --git a/backend/src/services/emailIntakeService.js b/backend/src/services/emailIntakeService.js index ebcd1220..bcfebb06 100644 --- a/backend/src/services/emailIntakeService.js +++ b/backend/src/services/emailIntakeService.js @@ -138,8 +138,12 @@ async function roundTripTest({ timeoutMs = 30000, intervalMs = 3000 } = {}) { if (!c.imap_host || !c.imap_user) return { ok: false, sent: false, reason: 'imap_unconfigured' }; // Recipient = the mailbox we poll. imap_user is the mailbox address in the - // typical setup (e.g. rechnungen@…). + // typical setup (e.g. rechnungen@…). NOT hardcoded — but some hosts use a + // non-email IMAP login, in which case we can't auto-address the test. const recipient = c.imap_user; + if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(recipient || '')) { + return { ok: false, sent: false, reason: 'recipient_not_email', recipient }; + } const token = `ppk-rt-${Date.now()}-${crypto.randomBytes(5).toString('hex')}`; const subject = `picpeak round-trip test ${token}`;