diff --git a/back/db/message/updateMessage-db.ts b/back/db/message/updateMessage-db.ts new file mode 100644 index 0000000..ab09221 --- /dev/null +++ b/back/db/message/updateMessage-db.ts @@ -0,0 +1,30 @@ +import { execQuery, execQueryAsync, execQueryAsyncWithId } from "../db"; + +export async function getFlags(uid: number): Promise<{flag_id: number, flag_name: string}[]> { + const query = ` + SELECT * FROM flag_name + INNER JOIN flag ON flag.flag_id = flag_name.flag_id + INNER JOIN mailbox_message ON mailbox_message.message_id = flag.message_id + WHERE mailbox_message.uid = ? + `; + const values = [uid]; + return await execQueryAsync(query, values); +} + +export async function deleteFlag(messageId: number, flagId: number) { + const query = `DELETE FROM flag WHERE message_id = ? AND flag_id = ?`; + const values = [messageId, flagId]; + execQuery(query, values); +} + +export async function updateMailboxSeen(messageId: number, isSeen: boolean) { + const query = `UPDATE mailbox_message SET seen = ? WHERE message_id = ?`; + const values = [messageId, isSeen]; + return await execQueryAsync(query, values); +} + +export async function updateMailboxDeleted(messageId: number, isDeleted: boolean) { + const query = `UPDATE mailbox_message SET deleted = ? WHERE message_id = ?`; + const values = [messageId, isDeleted]; + return await execQueryAsync(query, values); +} \ No newline at end of file diff --git a/back/db/utils/mail.ts b/back/db/utils/mail.ts index 166db17..74aed4c 100644 --- a/back/db/utils/mail.ts +++ b/back/db/utils/mail.ts @@ -22,6 +22,12 @@ export async function getFlagId(flag: string): Promise { return await execQueryAsyncWithId(query, values); } +export async function getMessageIdOnUid(uid: number): Promise<{message_id: number}[]> { + const query = `SELECT message_id FROM mailbox_message WHERE uid = ?`; + const values = [uid]; + return await execQueryAsync(query, values); +} + export async function findRoomByOwner(ownerId: number): Promise<{ room_id: number }[]> { const query = `SELECT room_id FROM app_room WHERE owner_id = ?`; const values = [ownerId]; diff --git a/back/mails/imap/Mailbox.ts b/back/mails/imap/Mailbox.ts index 8106650..48e2d8f 100644 --- a/back/mails/imap/Mailbox.ts +++ b/back/mails/imap/Mailbox.ts @@ -2,8 +2,15 @@ import Imap, { ImapMessageAttributes, Box } from "imap"; import { getMailbox, updateMailbox } from "../../db/imap/imap-db"; import { Attrs, AttrsWithEnvelope } from "../../interfaces/mail/attrs.interface"; import logger from "../../system/Logger"; -import RegisterMessageInApp from "../saveMessage"; -import { saveMessage } from "../storeMessage"; +import RegisterMessageInApp from "../message/saveMessage"; +import { saveMessage } from "../message/storeMessage"; +import updateMessage from "../message/updateMessage"; + +export interface ImapInfo { + uid: number; + modseq: string; + flags: string[]; +} export default class Mailbox { imap: Imap; @@ -38,6 +45,7 @@ export default class Mailbox { logger.log("Already up to date") } + // wait for new mails this.imap.on("mail", (numNewMsgs: number) => { if (!this.syncing) { // if not syncing restart a sync @@ -47,6 +55,11 @@ export default class Mailbox { this.msgToSync += numNewMsgs; } }); + + this.imap.on("update", (seqno: number, info: ImapInfo) => { + const updateMsg = new updateMessage(info.uid, info.flags); + updateMsg.updateFlags(); + }); }); } diff --git a/back/mails/message/updateMessage.ts b/back/mails/message/updateMessage.ts new file mode 100644 index 0000000..2c7a2b8 --- /dev/null +++ b/back/mails/message/updateMessage.ts @@ -0,0 +1,43 @@ +import { registerFlag } from "../../db/message/storeMessage-db"; +import { deleteFlag, getFlags, updateMailboxDeleted, updateMailboxSeen } from "../../db/message/updateMessage-db"; +import { getFlagId, getMessageIdOnUid } from "../../db/utils/mail"; + +export default class updateMessage { + uid: number; + flags: string[]; + + constructor(_uid: number, _flags: string[]) { + this.uid = _uid; + this.flags = _flags; + } + + async updateFlags() { + const messageId = (await getMessageIdOnUid(this.uid))[0].message_id; + const currentFlags = await getFlags(this.uid); + + const flagsToAdd = this.flags.filter((flag) => !currentFlags.find((f) => flag == f.flag_name)); + const flagToRm = currentFlags.filter((f) => !this.flags.includes(f.flag_name)); + + flagsToAdd.forEach(async (flag) => { + const flagId = await getFlagId(flag); + registerFlag(messageId, flagId); + }); + + flagToRm.forEach(async (flag) => { + deleteFlag(messageId, flag.flag_id); + }); + + // todo update seen counter rooms + if (flagsToAdd.includes("\\Seen")) { + updateMailboxSeen(messageId, true); + } else if (flagToRm.find((f) => f.flag_name == "\\Seen")) { + updateMailboxSeen(messageId, false); + } + + if (flagsToAdd.includes("\\Deleted")) { + updateMailboxDeleted(messageId, true); + } else if (flagToRm.find((f) => f.flag_name == "\\Deleted")) { + updateMailboxDeleted(messageId, false); + } + } +}