diff --git a/back/controllers/messages.js b/back/controllers/messages.js index 8ce445c..913e673 100644 --- a/back/controllers/messages.js +++ b/back/controllers/messages.js @@ -4,7 +4,7 @@ const { getMessages } = require("../db/api.js"); async function messages(body, res) { const { roomId } = body; getMessages(roomId).then((messages) => { - res.status(statusCode.OK).json(messages.data); + res.status(statusCode.OK).json(messages); }).catch((err) => { console.log(err) res.status(statusCode.INTERNAL_SERVER_ERROR); diff --git a/back/db/api.js b/back/db/api.js index ca1f012..46f1ad2 100644 --- a/back/db/api.js +++ b/back/db/api.js @@ -12,9 +12,11 @@ async function registerMailbox(userId, pwd, xoauth, xoauth2, host, port, tls) { async function getMailboxes() { const query = ` - SELECT app_account.account_id AS id, address.email - FROM app_account INNER JOIN address - WHERE address.address_id = app_account.user_id + SELECT + app_account.account_id AS id, + address.email + FROM app_account INNER JOIN address + WHERE address.address_id = app_account.user_id `; const values = []; return await execQueryAsync(query, values); @@ -46,31 +48,68 @@ async function getRooms(mailboxId) { async function getMessages(roomId) { // todo attachements name + // todo html, text, textAsHtml + // todo datetime const query = ` SELECT - address_field.address_id, - bodypart.text, - header_field.value - FROM bodypart - INNER JOIN header_field - INNER JOIN address_field - INNER JOIN field_name + msg.message_id AS id, + GROUP_CONCAT(fromT.address_id) AS fromA, + GROUP_CONCAT(toT.address_id) AS toA, + GROUP_CONCAT(ccT.address_id) AS ccA, + subjectT.value AS subject, + content.text AS content, + message.idate AS date + FROM app_room_message msg + + LEFT JOIN ( + SELECT address_field.address_id, address_field.message_id + FROM address_field + INNER JOIN field_name WHERE - ( - header_field.field_id = field_name.field_id OR - address_field.field_id = field_name.field_id - ) AND - ( - field_name.field_name = 'html' OR - field_name.field_name = 'text' OR - field_name.field_name = 'textAsHtml' OR - field_name.field_name = 'to' OR - field_name.field_name = 'cc' OR - field_name.field_name = 'subject' - ) - `; - // todo roomID - const values = []; + field_name.field_id = address_field.field_id AND + field_name.field_name = 'from' + ) fromT ON msg.message_id = fromT.message_id + LEFT JOIN ( + SELECT address_field.address_id, address_field.message_id + FROM address_field + INNER JOIN field_name + WHERE + field_name.field_id = address_field.field_id AND + field_name.field_name = 'to' + ) toT ON msg.message_id = toT.message_id + LEFT JOIN ( + SELECT address_field.address_id, address_field.message_id + FROM address_field + INNER JOIN field_name + WHERE + field_name.field_id = address_field.field_id AND + field_name.field_name = 'cc' + ) ccT ON msg.message_id = ccT.message_id + + LEFT JOIN ( + SELECT header_field.message_id, header_field.value + FROM header_field + INNER JOIN field_name + WHERE + field_name.field_id = header_field.field_id AND + field_name.field_name = 'subject' + ) subjectT ON msg.message_id = subjectT.message_id + + LEFT JOIN ( + SELECT bodypart.text, header_field.message_id FROM bodypart + INNER JOIN header_field + INNER JOIN field_name + WHERE + field_name.field_id = header_field.field_id AND + field_name.field_name = 'html' AND + bodypart.bodypart_id = header_field.bodypart_id + ) content ON msg.message_id = content.message_id + + INNER JOIN message ON message.message_id = msg.message_id + WHERE msg.room_id = ? + GROUP BY msg.message_id; + `; + const values = [roomId]; return await execQueryAsync(query, values); } diff --git a/back/db/saveMessage.js b/back/db/saveMessage.js index e877054..8d36646 100644 --- a/back/db/saveMessage.js +++ b/back/db/saveMessage.js @@ -14,10 +14,10 @@ async function registerMessage(timestamp, rfc822size, messageId) { function registerMailbox_message(mailboxId, uid, messageId, modseq, seen, deleted) { const query = ` INSERT IGNORE INTO mailbox_message - (mailbox_id, uid, message_id, modseq, seen, deleted) VALUES (1, 19, 10, '12450', 0, 0) + (mailbox_id, uid, message_id, modseq, seen, deleted) VALUES (?, ?, ?, ?, ?, ?) `; - // todo const values = [mailboxId, uid, messageId, modseq, seen, deleted]; + console.log(values) execQuery(query, values); } diff --git a/back/db/saveMessageApp.js b/back/db/saveMessageApp.js index e5533db..b73bacb 100644 --- a/back/db/saveMessageApp.js +++ b/back/db/saveMessageApp.js @@ -9,7 +9,7 @@ async function createRoom(roomName, ownerId, messageId) { } async function registerMessageInRoom(messageId, roomId, isSeen) { - const query = `INSERT INTO app_space_message (message_id, room_id) VALUES (?, ?)`; + const query = `INSERT IGNORE INTO app_room_message (message_id, room_id) VALUES (?, ?)`; const values = [messageId, roomId]; await execQueryAsync(query, values); @@ -68,8 +68,8 @@ async function isRoomGroup(roomId) { }); } -async function findSpacesFromMessage(messageId) { - const query = `SELECT room_id, thread_id FROM app_space_message WHERE message_id = '${messageId}'`; +async function findRoomsFromMessage(messageId) { + const query = `SELECT room_id FROM app_room_message WHERE message_id = '${messageId}'`; return await execQueryAsync(query); } @@ -85,5 +85,5 @@ module.exports = { createThread, registerMessageInThread, isRoomGroup, - findSpacesFromMessage, + findRoomsFromMessage, }; diff --git a/back/db/structureV2.sql b/back/db/structureV2.sql index 2a0a99d..4fe13f2 100644 --- a/back/db/structureV2.sql +++ b/back/db/structureV2.sql @@ -131,25 +131,24 @@ CREATE TABLE app_room ( -- 12 CREATE TABLE app_thread ( - thread_id INT AUTO_INCREMENT, room_id INT NOT NULL, - thread_name VARCHAR(255) NOT NULL, - notSeen INT NOT NULL DEFAULT 0, - lastUpdate TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP(), + parent_room_id INT, + root_room_id INT, isDm BOOLEAN NOT NULL DEFAULT false, - PRIMARY KEY (thread_id), - FOREIGN KEY (room_id) REFERENCES app_room(room_id) ON DELETE CASCADE + PRIMARY KEY (room_id), + UNIQUE KEY (room_id, parent_room_id, root_room_id), + FOREIGN KEY (room_id) REFERENCES app_room(room_id) ON DELETE CASCADE, + FOREIGN KEY (parent_room_id) REFERENCES app_room(room_id) ON DELETE SET NULL, + FOREIGN KEY (root_room_id) REFERENCES app_room(room_id) ON DELETE SET NULL ); -- 13 -CREATE TABLE app_space_message ( +CREATE TABLE app_room_message ( message_id INT NOT NULL, room_id INT, - thread_id INT, - UNIQUE KEY (message_id, room_id, thread_id), + UNIQUE KEY (message_id, room_id), FOREIGN KEY (message_id) REFERENCES message(message_id) ON DELETE CASCADE, - FOREIGN KEY (room_id) REFERENCES app_room(room_id) ON DELETE SET NULL, - FOREIGN KEY (thread_id) REFERENCES app_thread(thread_id) ON DELETE SET NULL + FOREIGN KEY (room_id) REFERENCES app_room(room_id) ON DELETE SET NULL ); -- 14 @@ -159,11 +158,3 @@ CREATE TABLE app_room_member ( FOREIGN KEY (room_id) REFERENCES app_room(room_id) ON DELETE CASCADE, FOREIGN KEY (member_id) REFERENCES address(address_id) ); - --- 14 -CREATE TABLE app_thread_member ( - thread_id INT NOT NULL, - member_id INT NOT NULL, - FOREIGN KEY (thread_id) REFERENCES app_thread(thread_id) ON DELETE CASCADE, - FOREIGN KEY (member_id) REFERENCES address(address_id) -); diff --git a/back/imap/index.js b/back/imap/index.js index b2b3a41..ac18268 100644 --- a/back/imap/index.js +++ b/back/imap/index.js @@ -28,6 +28,7 @@ if (shouldReset) { execQuery("SET FOREIGN_KEY_CHECKS=0"); results.map((table) => { execQuery("DELETE FROM " + table.table_name); + // execQuery("DROP TABLE " + table.table_name); }); }); return; diff --git a/back/routes/mail.js b/back/routes/mail.js index 0035add..a3130d3 100644 --- a/back/routes/mail.js +++ b/back/routes/mail.js @@ -19,6 +19,7 @@ const validate_mailbox = ajv.compile(schema_mailbox); */ router.get("/mailboxes", (req, res) => { getMailboxes().then((data) => { + data[0].id = 1; // todo debug res.status(statusCodes.OK).json(data) }); }); @@ -49,9 +50,10 @@ router.get("/:roomId/messages", async (req, res) => { * Register a new mailbox inside the app */ router.post("/mailbox", async (req, res) => { + console.log(req.body) const valid = validate_mailbox(req.body); if (!valid) { - res.status(statusCodes.NOT_ACCEPTABLE).send(validate_mailbox.errors) + res.status(statusCodes.NOT_ACCEPTABLE).send({ error: validate_mailbox.errors }); } else { await addMailbox(req.body, res); } diff --git a/front/src/store/models/Room.js b/front/src/store/models/Room.js new file mode 100644 index 0000000..114ec85 --- /dev/null +++ b/front/src/store/models/Room.js @@ -0,0 +1,13 @@ +export default class Room { + constructor(id, user, userId, roomName, mailboxId) { + this.id = id; + this.user = user; + this.userId = userId; + this.roomName = roomName; + this.mailboxId = mailboxId; + + this.messages = []; + this.messagesFetched = false; + this.threads = []; + } +} \ No newline at end of file diff --git a/front/src/store/store.js b/front/src/store/store.js index 428d87b..5e37586 100644 --- a/front/src/store/store.js +++ b/front/src/store/store.js @@ -1,42 +1,19 @@ import API from "@/services/imapAPI"; import { createStore } from "vuex"; +import Room from "./models/Room"; const store = createStore({ state() { return { rooms: [ - { - id: 0, - user: "clemnce", - userId: 0, - roomName: "Lorem magna minim cillum labore ex eiusmod proident excepteur sint irure ipsum.", - mailboxId: 1, - }, - { - id: 1, - user: "juliette", - roomName: "Lorem magna minim cillum labore ex eiusmod proident excepteur sint irure ipsum.", - mailboxId: 1, - }, - { - id: 2, - user: "jean", - roomName: "Lorem magna minim cillum labore ex eiusmod proident excepteur sint irure ipsum.", - mailboxId: 2, - }, - { - id: 3, - user: "luc", - roomName: "Lorem magna minim cillum labore ex eiusmod proident excepteur sint irure ipsum.", - mailboxId: 2, - }, - ], - messages: [ - + new Room(1, "clemence", 0, "Est ex adipisicing non ipsum voluptate duis enim adipisicing labore.", 1), + new Room(2, "laurance", 0, "Est ex adipisicing non ipsum voluptate duis enim adipisicing labore.", 2), + new Room(3, "mathilde", 0, "Est ex adipisicing non ipsum voluptate duis enim adipisicing labore.", 1), ], + messages: [], mailboxes: [], activeMailbox: 0, - activeRoom: 0 + activeRoom: 0, }; }, mutations: { @@ -48,16 +25,18 @@ const store = createStore({ const mailbox = state.mailboxes.find((mailbox) => mailbox.id == payload); // todo fetched mailbox all if (mailbox?.fetched == false) { - API.getRooms(payload).then((res) => { - // todo add if not exist - mailbox.fetched = true; - res.data.forEach((room) => { - room.fetched = false; - state.rooms.push(room); + API.getRooms(payload) + .then((res) => { + // todo add if not exist + console.log(res.data) + mailbox.fetched = true; + res.data.forEach((room) => { + state.rooms.push(new Room(room.id, room.user, room.userId, room.roomName, room.mailboxId)); + }); + }) + .catch((err) => { + console.log(err); }); - }).catch((err) => { - console.log(err) - }); } }, setActiveRoom(state, payload) { @@ -66,24 +45,35 @@ const store = createStore({ // fetch messages for this room if not already fetched const room = state.rooms.find((room) => room.id == payload); if (!room || room?.fetched == false) { - console.log("add messages") - API.getMessages(payload).then((res) => { - // todo add if not exist - room.fetched = true; - res.data.forEach((msg) => { - state.messages.push(msg); + console.log("add messages"); + API.getMessages(payload) + .then((res) => { + // todo add if not exist + room.fetched = true; + res.data.forEach((msg) => { + state.messages.push(msg); + }); + }) + .catch((err) => { + console.log(err); }); - }).catch((err) => { - console.log(err) - }); } }, addMailboxes(state, payload) { + console.log(payload) payload.forEach((mailbox) => { mailbox.fetched = false; state.mailboxes.push(mailbox); }); }, + addMessages(state, payload) { + const room = state.rooms.find((room) => room.id == payload.roomId); + payload.messages.forEach((message) => { + room.messages.push(message); + }); + room.messagesFetched = true; + console.log(room.messages) + }, }, getters: { rooms: (state) => () => { @@ -91,16 +81,16 @@ const store = createStore({ return state.rooms.filter((room) => room.mailboxId == state.activeMailbox); }, messages: (state) => (roomId) => { - const room = state.rooms.find((room) => room.id === roomId); - if (room?.fetched === false) { - console.log("ok") + const room = state.rooms.find((room) => room.id == roomId); + if (!room.messagesFetched) { + console.log("fetched Messages") + store.dispatch("fetchMessages", { roomId: room.id }); } - return [1, 2]; - } + return room.messages; + }, }, actions: { - async fetchMailboxes(context) { - console.log("add mailboxes"); + fetchMailboxes: async (context) => { API.getMailboxes() .then((res) => { context.commit("addMailboxes", res.data); @@ -109,8 +99,15 @@ const store = createStore({ console.log(err); }); }, - async fetchMessages(context) { - console.log(context) + fetchMessages: async (context, data) => { + API.getMessages(data.roomId) + .then((res) => { + console.log(res.data) + context.commit("addMessages", { messages: res.data, roomId: data.roomId }); + }) + .catch((err) => { + console.log(err); + }); }, }, }); diff --git a/front/src/views/room/Header.vue b/front/src/views/room/Header.vue index 569ebc8..b3fba54 100644 --- a/front/src/views/room/Header.vue +++ b/front/src/views/room/Header.vue @@ -19,7 +19,7 @@ export default { diff --git a/front/src/views/room/RoomView.vue b/front/src/views/room/RoomView.vue index 0ed0c29..e7cab46 100644 --- a/front/src/views/room/RoomView.vue +++ b/front/src/views/room/RoomView.vue @@ -14,7 +14,8 @@ onBeforeMount(async () => { console.log(store.state.rooms.find((room) => room.id === id)?.fetched); let room = store.state.rooms.find((room) => room.id === id); if (!room || room?.fetched === false) { - await store.dispatch("fetchMessages"); + // todo + // await store.dispatch("fetchMessages", ); } store.commit("setActiveRoom", id); }); @@ -28,20 +29,49 @@ onBeforeRouteUpdate(async (to, from) => { - + - - - {{ id }} - {{ messages.length }} + + + + {{ id }} + {{ messages.length }} + + COMPOSER