feat(email): incoming mail (IMAP) intake - backend + standalone flag
Adds a second mail config (incoming/IMAP) alongside the outgoing SMTP one, a 1-minute poller, and a received-emails log. Standalone `incomingMail` feature flag (default off). - deps: imapflow + mailparser (receive-side; picpeak only had nodemailer). - migration 128: email_configs gains imap_* columns (same shape as smtp_*); seed incomingMail flag; new received_emails audit table. - emailIntakeService: polls the mailbox every 60s when the flag is on AND a mailbox is configured (no-op otherwise); parses each unseen message (mailparser flattens forwarded/nested attachments), drops PDF/JPEG/PNG into the incoming-invoices inbox (inbound_documents, source='email'), logs each message in received_emails (dedupe by message-id; duplicate attachments caught by the existing SHA-256 guard), marks it \Seen. - adminEmail: GET/POST /incoming-config (mirrors SMTP config, masks imap_pass, SSRF host guard) + GET /received (paginated log). - server.js starts the poller at boot. Verified: node -c, require-graph, migration-128 harness (imap columns, flag, received_emails). Frontend (IMAP block under SMTP + Received tab + flag card) follows.
This commit is contained in:
+10
-1
@@ -836,7 +836,16 @@ async function startServer() {
|
||||
logger.warn('Email template self-heal failed at boot:', err.message);
|
||||
}
|
||||
startEmailQueueProcessor();
|
||||
|
||||
|
||||
// Start incoming-mail (IMAP) poller — no-ops each minute unless the
|
||||
// `incomingMail` flag is on and a mailbox is configured (migration 128).
|
||||
try {
|
||||
const { startIncomingMailPoller } = require('./src/services/emailIntakeService');
|
||||
startIncomingMailPoller();
|
||||
} catch (err) {
|
||||
logger.warn('Incoming-mail poller failed to start:', err.message);
|
||||
}
|
||||
|
||||
// Start webhook delivery worker (#327)
|
||||
const { startWebhookDeliveryWorker } = require('./src/services/webhookDeliveryWorker');
|
||||
startWebhookDeliveryWorker();
|
||||
|
||||
Reference in New Issue
Block a user