mailu branch failed
This commit is contained in:
12
backend/Dockerfile
Normal file
12
backend/Dockerfile
Normal file
@@ -0,0 +1,12 @@
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
|
||||
COPY . .
|
||||
|
||||
EXPOSE 5182
|
||||
|
||||
CMD [ "node", "app.js" ]
|
||||
32
backend/app.js
Normal file
32
backend/app.js
Normal file
@@ -0,0 +1,32 @@
|
||||
const express = require('express');
|
||||
const cors = require('cors');
|
||||
const db = require('./db');
|
||||
|
||||
const app = express();
|
||||
const port = 5182;
|
||||
|
||||
app.use(cors());
|
||||
app.use(express.json());
|
||||
|
||||
// API to get messages for a recipient
|
||||
app.get('/api/messages', async (req, res) => {
|
||||
const { recipient } = req.query;
|
||||
if (!recipient) {
|
||||
return res.status(400).send('Recipient is required');
|
||||
}
|
||||
|
||||
try {
|
||||
const [rows] = await db.execute(
|
||||
'SELECT id, sender, subject, body, received_at FROM emails WHERE recipient = ? ORDER BY received_at DESC',
|
||||
[recipient]
|
||||
);
|
||||
res.json(rows);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch emails:', error);
|
||||
res.status(500).send('Failed to fetch emails');
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Backend server listening at http://localhost:${port}`);
|
||||
});
|
||||
13
backend/db.js
Normal file
13
backend/db.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const mysql = require('mysql2');
|
||||
|
||||
const pool = mysql.createPool({
|
||||
host: process.env.DB_HOST,
|
||||
user: process.env.DB_USER,
|
||||
password: process.env.DB_PASSWORD,
|
||||
database: process.env.DB_NAME,
|
||||
waitForConnections: true,
|
||||
connectionLimit: 10,
|
||||
queueLimit: 0
|
||||
});
|
||||
|
||||
module.exports = pool.promise();
|
||||
18
backend/init.sql
Normal file
18
backend/init.sql
Normal file
@@ -0,0 +1,18 @@
|
||||
CREATE TABLE IF NOT EXISTS emails (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
recipient VARCHAR(255) NOT NULL,
|
||||
sender VARCHAR(255) NOT NULL,
|
||||
subject VARCHAR(512),
|
||||
body TEXT,
|
||||
received_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
raw MEDIUMBLOB
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS email_attachments (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
email_id BIGINT NOT NULL,
|
||||
filename VARCHAR(255),
|
||||
content_type VARCHAR(128),
|
||||
content LONGBLOB,
|
||||
FOREIGN KEY (email_id) REFERENCES emails(id) ON DELETE CASCADE
|
||||
);
|
||||
16
backend/package.json
Normal file
16
backend/package.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "backend",
|
||||
"version": "1.0.0",
|
||||
"description": "Backend for email service",
|
||||
"main": "app.js",
|
||||
"scripts": {
|
||||
"start": "node app.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^5.1.0",
|
||||
"mysql2": "^3.14.2",
|
||||
"mailparser": "^3.7.4",
|
||||
"cors": "^2.8.5",
|
||||
"get-stream": "^9.0.1"
|
||||
}
|
||||
}
|
||||
54
backend/saveEmail.js
Normal file
54
backend/saveEmail.js
Normal file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { simpleParser } = require('mailparser');
|
||||
const db = require('./db');
|
||||
|
||||
// Using require for get-stream v5 as it's CommonJS
|
||||
const getStream = require('get-stream');
|
||||
|
||||
async function saveEmail(rawEmail) {
|
||||
try {
|
||||
const parsed = await simpleParser(rawEmail);
|
||||
|
||||
// Ensure 'to' and 'from' objects exist before accessing 'text'
|
||||
const recipient = parsed.to ? parsed.to.text : 'undisclosed-recipients';
|
||||
const sender = parsed.from ? parsed.from.text : 'unknown-sender';
|
||||
const subject = parsed.subject;
|
||||
const body = parsed.text || (parsed.html || '');
|
||||
|
||||
const [result] = await db.execute(
|
||||
'INSERT INTO emails (recipient, sender, subject, body, raw) VALUES (?, ?, ?, ?, ?)',
|
||||
[recipient, sender, subject, body, rawEmail]
|
||||
);
|
||||
|
||||
console.log(`Email saved with ID: ${result.insertId}`);
|
||||
|
||||
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 (?, ?, ?, ?)',
|
||||
[result.insertId, attachment.filename, attachment.contentType, attachment.content]
|
||||
);
|
||||
console.log(`Attachment ${attachment.filename} saved.`);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to save email:', error);
|
||||
// Exit with an error code to signal failure to the calling process (e.g., Mailu)
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const rawEmail = await getStream(process.stdin);
|
||||
if (rawEmail && rawEmail.length > 0) {
|
||||
await saveEmail(rawEmail);
|
||||
} else {
|
||||
console.log('Received empty input, no email to save.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error reading from stdin:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user