advancement on logic of app
This commit is contained in:
@@ -14,6 +14,27 @@ const imap = new Imap({
|
||||
tls: true,
|
||||
});
|
||||
|
||||
// reset table;
|
||||
|
||||
let shouldReset = false;
|
||||
// let shouldReset = true;
|
||||
|
||||
if (shouldReset) {
|
||||
|
||||
|
||||
const { execQuery, execQueryAsync } = require("../sql/bdd");
|
||||
const query =
|
||||
"SELECT table_name FROM INFORMATION_SCHEMA.tables WHERE table_schema = 'mail'";
|
||||
execQueryAsync(query).then((results) => {
|
||||
execQuery("SET FOREIGN_KEY_CHECKS=0");
|
||||
results.map((table) => {
|
||||
execQuery("DELETE FROM " + table.table_name);
|
||||
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
imap.once("ready", function () {
|
||||
const readOnly = true;
|
||||
imap.openBox("INBOX", readOnly, (err, box) => {
|
||||
@@ -22,7 +43,11 @@ imap.once("ready", function () {
|
||||
console.log(results[results.length - 1]);
|
||||
});
|
||||
|
||||
const f = imap.fetch(970, { size: true, struct: true, envelope: true });
|
||||
const f = imap.fetch(970, {
|
||||
size: true,
|
||||
struct: true,
|
||||
envelope: true,
|
||||
});
|
||||
// var f = imap.seq.fetch('1:3', {
|
||||
// bodies: 'HEADER.FIELDS (FROM TO SUBJECT DATE)',
|
||||
// struct: true
|
||||
@@ -42,7 +67,7 @@ imap.once("ready", function () {
|
||||
// // console.log(prefix + 'Body');
|
||||
// // stream.pipe(fs.createWriteStream('msg-' + seqno + '-body.txt'));
|
||||
// });
|
||||
msg.once('attributes', attrs => {
|
||||
msg.once("attributes", (attrs) => {
|
||||
// todo find boxId
|
||||
const boxId = 1;
|
||||
// console.log(attrs)
|
||||
@@ -50,9 +75,6 @@ imap.once("ready", function () {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
f.once("error", function (err) {
|
||||
console.log("Fetch error: " + err);
|
||||
});
|
||||
@@ -135,7 +157,6 @@ imap.once("end", function () {
|
||||
|
||||
imap.connect();
|
||||
|
||||
|
||||
function isValidEmail(email) {
|
||||
// todo
|
||||
return true;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const { getAddresseId } = require("../sql/mail");
|
||||
const { DEBUG } = require("../utils/debug");
|
||||
const { simpleParser } = require("mailparser");
|
||||
const moment = require('moment');
|
||||
const moment = require("moment");
|
||||
const {
|
||||
registerMessage,
|
||||
registerMailbox_message,
|
||||
@@ -17,99 +17,121 @@ const {
|
||||
createThread,
|
||||
registerMessageInThread,
|
||||
isRoomGroup,
|
||||
findSpacesFromMessage
|
||||
findSpacesFromMessage,
|
||||
hasSameMembersAsParent,
|
||||
} = require("../sql/saveMessageApp");
|
||||
const { getFieldId, findRoomByOwner } = require("../sql/mail");
|
||||
|
||||
function saveMessage(attrs, mailboxId, imap) {
|
||||
const envelope = attrs.envelope;
|
||||
const timestamp = moment(new Date(envelope.date).getTime()).format('YYYY-MM-DD HH:mm:ss');
|
||||
const rfc822size = attrs.size;
|
||||
|
||||
registerMessage(timestamp, rfc822size, envelope.messageId).then(
|
||||
(messageId) => {
|
||||
const seen = attrs.flags.includes("Seen") ? 1 : 0; // todo verify
|
||||
const deleted = attrs.flags.includes("Deleted") ? 1 : 0; // todo verify
|
||||
|
||||
registerMailbox_message(
|
||||
mailboxId,
|
||||
attrs.uid,
|
||||
messageId,
|
||||
attrs.modseq,
|
||||
seen,
|
||||
deleted
|
||||
);
|
||||
|
||||
const len = attrs.struct.length;
|
||||
attrs.struct.forEach((part) => {
|
||||
if (len > 1) part = part[0];
|
||||
|
||||
// todo should be recursive to take eveyraçpghyrue
|
||||
// todo attachments
|
||||
if (part?.type == "text") {
|
||||
const registerType = `${part.type}/${part.subtype}`
|
||||
const hash = "2"; // todo
|
||||
const text = "1"; // todo
|
||||
saveBodypart(part.size, hash, text, '').then((bodypartId) => {
|
||||
registerBodypart(messageId, registerType, bodypartId, part.size, part.lines);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// const fetch = imap.fetch(uid, { bodies: ["HEADER", part.partID] });
|
||||
|
||||
// fetch.on("message", (msg) => {
|
||||
// msg.on("body", (stream, info) => {
|
||||
// simpleParser(stream, async (err, parsed) => {
|
||||
// console.log(part.partID, parsed?.subject);
|
||||
// });
|
||||
// });
|
||||
|
||||
// msg.once("end", () => {
|
||||
// console.log("Finished fetching message");
|
||||
// });
|
||||
// });
|
||||
|
||||
// fetch.once("error", (err) => {
|
||||
// console.log(err);
|
||||
// });
|
||||
|
||||
// fetch.once("end", () => {
|
||||
// console.log("Done fetching all messages");
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
|
||||
// todo when transfered
|
||||
//The part column records to which MIME part this header field belongs. It's empty for the main header (the one seen above) and nonempty when a multipart message has headers on each part.
|
||||
const part = ''; // todo ^
|
||||
const position = 2; // todo
|
||||
// save envelope (header + from, to, subject, date, cc)
|
||||
Object.keys(envelope).forEach(key => {
|
||||
const newKey = keyNormalizer(key);
|
||||
if (isHeader(newKey)) {
|
||||
getFieldId(newKey).then((fieldId) => {
|
||||
saveHeader_fields(messageId, part, position, fieldId, envelope[key]);
|
||||
});
|
||||
} else {
|
||||
getFieldId(newKey).then((fieldId) => {
|
||||
if (envelope[key]) {
|
||||
envelope[key].forEach((elt, index) => {
|
||||
getAddresseId(createAddress(elt)).then((addressId) => {
|
||||
saveAddress_fields(messageId, part, position, fieldId, index, addressId);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// todo check for different provider name of inreplyto
|
||||
// registerMessageInApp(envelope, messageId);
|
||||
console.log(envelope)
|
||||
|
||||
}
|
||||
const timestamp = moment(new Date(envelope.date).getTime()).format(
|
||||
"YYYY-MM-DD HH:mm:ss"
|
||||
);
|
||||
const rfc822size = attrs.size;
|
||||
const messageID = envelope.messageId;
|
||||
|
||||
registerMessage(timestamp, rfc822size, messageID).then((messageId) => {
|
||||
const isSeen = attrs.flags.includes("Seen") ? 1 : 0; // todo verify
|
||||
const deleted = attrs.flags.includes("Deleted") ? 1 : 0; // todo verify
|
||||
|
||||
registerMailbox_message(
|
||||
mailboxId,
|
||||
attrs.uid,
|
||||
messageId,
|
||||
attrs.modseq,
|
||||
isSeen,
|
||||
deleted
|
||||
);
|
||||
|
||||
const len = attrs.struct.length;
|
||||
attrs.struct.forEach((part) => {
|
||||
|
||||
if (len > 1) part = part[0];
|
||||
// todo should be recursive to take eveyraçpghyrue
|
||||
// todo attachments
|
||||
console.log("parr", part)
|
||||
if (part?.type == "text") {
|
||||
console.log(attrs.uid, part.partID)
|
||||
const fetch = imap.fetch(attrs.uid, { bodies: ['', part.partID] });
|
||||
|
||||
fetch.on("message", (msg) => {
|
||||
msg.on("body", (stream, info) => {
|
||||
simpleParser(stream, async (err, parsed) => {
|
||||
console.log(part.partID, parsed?.subject);
|
||||
});
|
||||
});
|
||||
|
||||
msg.once("end", () => {
|
||||
console.log("Finished fetching message");
|
||||
});
|
||||
|
||||
});
|
||||
fetch.once("error", (err) => {
|
||||
console.log(err);
|
||||
});
|
||||
|
||||
fetch.once("end", () => {
|
||||
console.log("Done fetching all messages");
|
||||
});
|
||||
const registerType = `${part.type}/${part.subtype}`;
|
||||
const hash = "2"; // todo
|
||||
const text = "1"; // todo
|
||||
saveBodypart(part.size, hash, text, "").then((bodypartId) => {
|
||||
registerBodypart(
|
||||
messageId,
|
||||
registerType,
|
||||
bodypartId,
|
||||
part.size,
|
||||
part.lines
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
// todo when transfered
|
||||
//The part column records to which MIME part this header field belongs. It's empty for the main header (the one seen above) and nonempty when a multipart message has headers on each part.
|
||||
const part = ""; // todo ^
|
||||
// save envelope (header + from, to, subject, date, cc)
|
||||
// Object.keys(envelope).forEach((key, position) => {
|
||||
// const newKey = keyNormalizer(key);
|
||||
// if (isHeader(newKey)) {
|
||||
// getFieldId(newKey).then((fieldId) => {
|
||||
// saveHeader_fields(
|
||||
// messageId,
|
||||
// part,
|
||||
// position,
|
||||
// fieldId,
|
||||
// envelope[key]
|
||||
// );
|
||||
// });
|
||||
// } else {
|
||||
// getFieldId(newKey).then((fieldId) => {
|
||||
// if (!envelope[key]) {
|
||||
// return;
|
||||
// }
|
||||
// envelope[key].forEach((elt, index) => {
|
||||
// getAddresseId(createAddress(elt)).then((addressId) => {
|
||||
// saveAddress_fields(
|
||||
// messageId,
|
||||
// part,
|
||||
// position,
|
||||
// fieldId,
|
||||
// index,
|
||||
// addressId
|
||||
// );
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
|
||||
// todo check for different provider name of inreplyto
|
||||
// registerMessageInApp(envelope, messageId, isSeen);
|
||||
}).catch((err) => {
|
||||
DEBUG.log("Unable to register message: "+err);
|
||||
});
|
||||
}
|
||||
|
||||
function haveSameReceivers() {
|
||||
@@ -120,46 +142,73 @@ function haveSameReceivers() {
|
||||
* take object address and join mailbox and host to return mailbox@host
|
||||
*/
|
||||
function createAddress(elt) {
|
||||
return `${elt.mailbox}@${elt.host}`
|
||||
return `${elt.mailbox}@${elt.host}`;
|
||||
}
|
||||
|
||||
function registerMessageInApp(envelope, messageId) {
|
||||
function registerMessageInApp(envelope, messageId, isSeen) {
|
||||
getAddresseId(createAddress(envelope.sender[0])).then((ownerId) => {
|
||||
if (envelope.inReplyTo) {
|
||||
registerReplyMessage();
|
||||
registerReplyMessage(envelope, messageId, isSeen);
|
||||
} else {
|
||||
findRoomByOwner(ownerId).then((res) => {
|
||||
if (res.length == 0) {
|
||||
registerMessageInRoom(messageId, res[0].id);
|
||||
} else {
|
||||
createRoom(envelope.subject, ownerId, envelope.flags.includes["seen"]).then((roomId) => {
|
||||
registerMessageInRoom(messageId, roomId);
|
||||
console.log(res, ownerId)
|
||||
createRoom(envelope.subject, ownerId).then((roomId) => {
|
||||
registerMessageInRoom(messageId, roomId, isSeen);
|
||||
});
|
||||
} else {
|
||||
registerMessageInRoom(messageId, res[0].room_id, isSeen);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function registerReplyMessage(envelope, messageId) {
|
||||
function registerReplyMessage(envelope, messageId, isSeen) {
|
||||
const messageID = envelope.messageId;
|
||||
findSpacesFromMessage(messageId).then((spaces) => {
|
||||
if(spaces.length == 0) { // no space, so is a transfer
|
||||
// todo sub thread will not be in index 0 so look in all indexes
|
||||
if (spaces.length == 0) {
|
||||
// no space, so is a transfer
|
||||
// todo test if members of transferred message are included
|
||||
} else if (spaces[0].room) { // message in room
|
||||
} else if (spaces[0].thread_id) {
|
||||
registerMessageInThread(messageId, spaces[0].thread_id, isSeen);
|
||||
// todo
|
||||
// if (hasSameMembersAsParent(messageID, envelope.inReplyTo)) {
|
||||
// // register new message in thread
|
||||
// // possibly convert to room only if parent is channel
|
||||
// } else {
|
||||
// // todo create sub thread
|
||||
// }
|
||||
} else if (spaces[0].room_id) {
|
||||
// message in room and not thread
|
||||
isRoomGroup(spaces[0].room_id).then((isGroup) => {
|
||||
if (isGroup) {
|
||||
if (hasSameMembersAsParent(messageId)) {
|
||||
registerMessageInRoom(messageId, spaces[0].room_id);
|
||||
if (hasSameMembersAsParent(messageID, envelope.inReplyTo)) {
|
||||
registerMessageInRoom(
|
||||
messageId,
|
||||
spaces[0].room_id,
|
||||
isSeen
|
||||
);
|
||||
} else {
|
||||
// group and not the same member as the reply
|
||||
// some recipient has been removed create a thread
|
||||
const notSeen = 0; // todo
|
||||
const isDm = 0; // todo
|
||||
createThread(space[0].room_id, envelope.subject, notSeen, isDm).then((threadId) => {
|
||||
registerMessageInThread(messageId, threadId);
|
||||
createThread(
|
||||
space[0].room_id,
|
||||
envelope.subject,
|
||||
isSeen,
|
||||
isDm
|
||||
).then((threadId) => {
|
||||
registerMessageInThread(
|
||||
messageId,
|
||||
threadId,
|
||||
isSeen
|
||||
);
|
||||
});
|
||||
}
|
||||
} else { // reply from channel
|
||||
} else {
|
||||
// reply from channel
|
||||
// todo
|
||||
// if (messageInRoom == 1) { // was new channel transform to group
|
||||
// // register new message in group
|
||||
@@ -170,39 +219,30 @@ function registerReplyMessage(envelope, messageId) {
|
||||
// }
|
||||
}
|
||||
});
|
||||
} else if (spaces[0].thread) { // message in thread
|
||||
// todo
|
||||
// if (hasSameMembersAsParent(messageId)) {
|
||||
// // register new message in thread
|
||||
// // possibly convert to room only if parent is channel
|
||||
// } else {
|
||||
// // create sub thread
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// `SELECT app_room_messages.room, app_room_messages.thread FROM app_room_messages INNER JOIN messages WHERE messages.messageID = '${envelope.inReplyTo}' AND app_room_messages.message = messages.id`;
|
||||
|
||||
}
|
||||
|
||||
function findTextPart(struct) {
|
||||
for (var i = 0, len = struct.length, r; i < len; ++i) {
|
||||
if (Array.isArray(struct[i])) {
|
||||
if (r = findTextPart(struct[i]))
|
||||
return r;
|
||||
} else if (struct[i].type === 'text'
|
||||
&& (struct[i].subtype === 'plain'
|
||||
|| struct[i].subtype === 'html'))
|
||||
return [struct[i].partID, struct[i].type + '/' + struct[i].subtype];
|
||||
if (Array.isArray(struct[i])) {
|
||||
if ((r = findTextPart(struct[i]))) return r;
|
||||
} else if (
|
||||
struct[i].type === "text" &&
|
||||
(struct[i].subtype === "plain" || struct[i].subtype === "html")
|
||||
)
|
||||
return [struct[i].partID, struct[i].type + "/" + struct[i].subtype];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isHeader(key) {
|
||||
switch (key) {
|
||||
case "date":
|
||||
case "subject":
|
||||
case "messageId":
|
||||
case "inReplyTo": // when transfer or reply to message
|
||||
case "inReplyTo": // when transfer or reply to message
|
||||
return true;
|
||||
case "from":
|
||||
case "sender":
|
||||
|
||||
Reference in New Issue
Block a user