link imap sync to server and show email on front

This commit is contained in:
grimhilt
2023-03-26 14:20:16 +02:00
parent b156c5954d
commit d0d666f4cb
17 changed files with 266 additions and 64 deletions

59
back/mails/imap/Box.js Normal file
View File

@@ -0,0 +1,59 @@
const { getMailbox, updateMailbox } = require("../../db/imap/imap");
const { DEBUG } = require("../../utils/debug");
const { registerMessageInApp } = require("../saveMessage");
const { saveMessage } = require("../storeMessage");
class Box {
constructor(_imap, boxId, _boxName) {
this.imap = _imap;
this.boxName = _boxName;
this.id = boxId;
this.box;
this.init();
}
async init() {
this.box = (await getMailbox(this.id))[0];
const readOnly = true;
this.imap.openBox(this.boxName, readOnly, (err, box) => {
if (err) DEBUG.log(err);
this.sync(this.box.uidnext, box.uidnext);
});
}
sync(savedUid, currentUid) {
const promises = [];
const mails = [];
console.log(savedUid, currentUid);
const f = this.imap.seq.fetch(`${savedUid}:${currentUid}`, {
size: true,
envelope: true,
});
f.on("message", (msg, seqno) => {
msg.once("attributes", (attrs) => {
mails.push(attrs);
promises.push(saveMessage(attrs, this.id, this.imap));
});
});
f.once("error", (err) => {
DEBUG.log("Fetch error: " + err);
});
f.once("end", async () => {
await Promise.all(promises).then(async (res) => {
for (let i = 0; i < mails.length; i++) {
console.log(i, mails[i].uid)
await registerMessageInApp(res[i], mails[i]);
}
});
updateMailbox(this.id, currentUid);
});
}
}
module.exports = {
Box,
};

View File

@@ -0,0 +1,73 @@
const Imap = require("imap");
const { getAllMailboxes, registerMailbox } = require("../../db/imap/imap");
const { DEBUG } = require("../../utils/debug");
const { Box } = require("./Box");
class ImapInstance {
constructor(account) {
this.imap = new Imap({
user: account.user,
password: account.password,
tlsOptions: { servername: account.host },
host: account.host,
port: account.port,
tls: account.tls,
});
this.account = account;
this.boxes = [];
/**
* IMAP
*/
this.imap.once("ready", () => {
DEBUG.log("imap connected")
this.imapReady();
});
this.imap.once("error", function (err) {
DEBUG.log(err);
});
this.imap.once("end", function () {
DEBUG.log("Connection ended");
});
this.imap.connect();
}
imapReady() {
getAllMailboxes(this.account.id).then((mailboxes) => {
if (mailboxes.length > 0) {
this.boxes.push(new Box(this.imap, mailboxes[0].mailbox_id, mailboxes[0].mailbox_name));
} else {
this.imap.getBoxes('', (err, boxes) => {
if (err) DEBUG.log(err);
const allBoxName = this.getAllBox(boxes);
registerMailbox(this.account.id, allBoxName).then((mailboxId) => {
this.boxes.push(new Box(this.imap, mailboxId, allBoxName));
});
});
}
});
}
getAllBox(boxes) {
// ideally we should get the all box to get all messages
let allBox;
Object.keys(boxes).forEach(key => {
if (key === 'INBOX') return;
allBox = key;
Object.keys(boxes[key].children).forEach((childBoxes) => {
if (boxes[key].children[childBoxes].attribs.includes('\\All')) {
allBox += '/' + childBoxes;
}
});
});
return allBox;
}
}
module.exports = {
ImapInstance
}

View File

@@ -0,0 +1,28 @@
const { getAllAccounts } = require("../../db/imap/imap");
const { DEBUG } = require("../../utils/debug");
const { ImapInstance } = require("./ImapInstance");
class ImapSync {
constructor() {
this.instances = [];
}
init() {
getAllAccounts().then((accounts) => {
for (let i = 0; i < accounts.length; i++) {
accounts[i].password = accounts[i]?.password.toString().replace(/[\u{0080}-\u{FFFF}]/gu,"");
this.addInstance(accounts[i]);
}
}).catch((err) => {
DEBUG.log(err);
});
}
addInstance(config) {
this.instances.push(new ImapInstance(config));
}
}
module.exports = {
ImapSync
}