70 lines
2.7 KiB
JavaScript
70 lines
2.7 KiB
JavaScript
const { simpleParser } = require('mailparser');
|
|
const db = require('./db');
|
|
const emitter = require('./eventEmitter');
|
|
const logger = require('./logger');
|
|
|
|
// Helper function to convert stream to buffer
|
|
function streamToBuffer(stream) {
|
|
return new Promise((resolve, reject) => {
|
|
const chunks = [];
|
|
stream.on('data', (chunk) => chunks.push(chunk));
|
|
stream.on('error', reject);
|
|
stream.on('end', () => resolve(Buffer.concat(chunks)));
|
|
});
|
|
}
|
|
|
|
async function saveEmail(stream) {
|
|
try {
|
|
// First, buffer the entire stream
|
|
const emailBuffer = await streamToBuffer(stream);
|
|
|
|
// Now, parse the buffered email content
|
|
const parsed = await simpleParser(emailBuffer);
|
|
const rawEmail = emailBuffer.toString();
|
|
|
|
const recipient = parsed.to ? parsed.to.text : 'undisclosed-recipients';
|
|
const sender = parsed.from ? parsed.from.text : 'unknown-sender';
|
|
const subject = parsed.subject || 'No Subject';
|
|
const body = parsed.text || (parsed.html || '');
|
|
|
|
// Manually create a timestamp for 'Asia/Shanghai' timezone
|
|
const received_at = new Date().toLocaleString('sv-SE', {
|
|
timeZone: 'Asia/Shanghai'
|
|
});
|
|
|
|
const [result] = await db.execute(
|
|
'INSERT INTO emails (recipient, sender, subject, body, raw, received_at) VALUES (?, ?, ?, ?, ?, ?)',
|
|
[recipient, sender, subject, body, rawEmail, received_at]
|
|
);
|
|
const newEmailId = result.insertId;
|
|
|
|
logger.info(`Email from <${sender}> to <${recipient}> saved with ID: ${newEmailId}`);
|
|
|
|
if (parsed.attachments && parsed.attachments.length > 0) {
|
|
for (const attachment of parsed.attachments) {
|
|
await db.execute(
|
|
'INSERT INTO email_attachments (email_id, filename, content_type, content) VALUES (?, ?, ?, ?)',
|
|
[newEmailId, attachment.filename, attachment.contentType, attachment.content]
|
|
);
|
|
logger.info(`Attachment ${attachment.filename} saved for email ID: ${newEmailId}`);
|
|
}
|
|
}
|
|
|
|
// Emit an event with the new email's main information
|
|
const [rows] = await db.execute('SELECT id, sender, recipient, subject, body, received_at FROM emails WHERE id = ?', [newEmailId]);
|
|
if (rows.length > 0) {
|
|
emitter.emit('newEmail', rows[0]);
|
|
logger.info(`Event 'newEmail' emitted for email ID: ${newEmailId}`);
|
|
}
|
|
|
|
} catch (error) {
|
|
logger.error('Failed to save email:', {
|
|
errorMessage: error.message,
|
|
errorStack: error.stack
|
|
});
|
|
// Re-throw the error so the caller (SMTPServer) can handle it.
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
module.exports = { saveEmail }; |