diff --git a/src/index.js b/src/index.js index cd2d22f..01bd17d 100644 --- a/src/index.js +++ b/src/index.js @@ -2,10 +2,10 @@ const express = require('express'); const bcrypt = require('bcrypt'); const cors = require("cors"); const WebSocket = require('ws'); -const http = require('http') +const http = require('http'); +const session = require('express-session'); -clients = []; // websocket clients -sessions = {}; // logged in clients, there are stored their tokens. +sessions = {}; // logged in clients, there are stored objects like {"token": "some_token_here", "socket": here-is-websocket-object} const middleware = require("./middleware"); const utils = require("./utils") @@ -20,21 +20,40 @@ const httpServer = http.createServer(app).listen(PORT, "0.0.0.0", () => { console.log("[LOG] Ready to use."); }); -const ws = new WebSocket.Server({ - server: httpServer, - host: "0.0.0.0" +const wss = new WebSocket.WebSocketServer({ clientTracking: false, noServer: true }); + +const onSocketError = (err) => { + console.error(err); +} + +httpServer.on('upgrade', (request, socket, head) => { + socket.on('error', onSocketError); + + sessionParser(request, {}, () => { + if (!request.session.token) { + socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n'); + socket.destroy(); + return; + } + socket.removeListener('error', onSocketError); + + wss.handleUpgrade(request, socket, head, function (ws) { + wss.emit('connection', ws, request); + }); + }); }); -console.log("[LOG] Socket has been started"); +wss.on('connection', function (ws, request) { + const token = request.session.token; -ws.on('connection', (wsclient) => { - clients.push(wsclient) + sessions[token].socket = ws; + + ws.on('error', console.error); /* Package structure: { "action": "...", // the request - "token": "...", // the token that is the key for sessions dictionary "content": ..., // the rest content of an action. } @@ -42,51 +61,91 @@ ws.on('connection', (wsclient) => { message: { "action": "message", - "token": "some_token_here", "content": { "chatId": 1, "text": "Hello!" } } */ + ws.on('message', async (message) => { + message = JSON.parse(message); + switch (message.action) { + case "message": { + let chatId = message.content.chatId; + let text = message.content.text; + let userId = sessions[token].userId - wsclient.on('message', async (msg) => { - try { - let jsonMsg = JSON.parse(msg) - switch (jsonMsg.action) { - case "message":{ - let userId = sessions[jsonMsg.token]; - console.log(`${userId} has sent a message: ${jsonMsg.content.text} to ${jsonMsg.content.chatId}`); + let r = await client.query("SELECT ID FROM Chats WHERE ID = $1", [chatId]); + if (r.rowCount == 0) { // no such chat exist + sessions[token].socket.send(`No chat with ID ${chatId} exist.`); break; } + if ((await client.query("SELECT ID FROM Users WHERE ID = $1 AND $2 = ANY(chats)", [userId, chatId])).rowCount == 0) { + ws.send("You are not a member of this chat."); + } - default: - console.log(`Package cannot be understood: ${msg}`) + //Inserting a message into database. + let messageId = (await client.query("INSERT INTO Messages (author_id, time_sent, content) VALUES($1, NOW(), $2) RETURNING ID", [userId, text])).rows[0].id; + await client.query("UPDATE Chats SET messages = ARRAY_APPEND(messages, $1) WHERE ID = $2", [messageId, chatId]) + // sessions[token].socket.send("successful"); + + //Sending a message to everyone who is in the group. + + let membersIds = (await client.query("SELECT ID FROM Users WHERE $1 = ANY(chats)", [chatId])).rows + let Ids = []; + for (let mId of membersIds) { + Ids.push(mId.id) + } + + // find all sessions by IDs and send to their sockets + for (const [key, value] of Object.entries(sessions)) { + let session = value; + if (session == undefined) continue + if (session.userId == userId) continue; // Skip the sender of the message + if (Ids.includes(session.userId)) { + session.socket.send(JSON.stringify({ + action: "message", + content: { + chatId: chatId, + authorId: userId, + text: text + } + })); + } + } + break; + } + default: { + console.log(`[ERROR] Package cannot be understood: ${JSON.stringify(message)}`); + sessions[token].socket.send("Package cannot be understood.") } - } catch (e) { - console.log(`[ERROR] in receiving message by websocket: ${e}`) } }); - wsclient.on('close', () => { - clients = clients.filter(c => c !== wsclient) - }) -}) + ws.on('close', function () { + // sessions[token].socket = undefined + }); +}); -app.use(cors()); -app.use(express.json()); -app.use(express.urlencoded({ extended: false })); -app.use(require('express-session')({ +console.log("[LOG] Socket has been started"); + +const sessionParser = session({ name: 'smk_chat', secret: 'PLEASE!!GENERATE!!A!!STRONG!!ONE!!', resave: false, saveUninitialized: false +}); -})); +app.use(cors()); +app.use(express.json()); +app.use(express.urlencoded({ extended: false })); +app.use(sessionParser); app.use('/js', express.static(__dirname + "/js")); + +//======================frontend=========================== app.get('/', middleware.requireToBeLoggedIn, (req, res) => { res.sendFile('views/index.html', { root: __dirname }); }); @@ -99,41 +158,124 @@ app.get('/login', middleware.requireToBeNotLoggedIn, (req, res) => { res.sendFile('views/login.html', { root: __dirname }); }); +app.get('/chat/:chatId', middleware.requireToBeLoggedIn, (req, res) => { + res.sendFile('views/chat.html', { root: __dirname }) +}); + +//======================backend=========================== + + +//IN: userId (in route) +//OUT: lastname, firstname, middlename +//Return credentials of the user whose id is userId. +//Return -1 if no such user exist. +//Requires client to be logged in. +app.get('/api/getCredentialsById/:id', middleware.requireToBeLoggedIn, async (req, res) => { + try { + const userId = req.params.id; + let user = (await client.query("SELECT lastname, firstname, middlename FROM Users WHERE ID = $1", [userId])).rows[0]; + if (user == undefined) return res.send("-1").status(400).end(); + return res.send(user).status(200).end(); + } catch (e) { + console.log(`[ERROR] in /api/getCredentialsById/${req.params.id}}: ${e}`) + res.status(500).send(); + } + +}); //IN: lastname, firstname, middlename //OUT: UserID //Returns an ID of the user, whose lastname, firstname and middlename were passed. //Returns -1 if user does not exist. //Requires client to be logged in. -app.get('/api/getIdByCredentials', middleware.requireToBeLoggedIn, async (req, res) => { - const { lastname, firstname, middlename } = req.body; - return res.send(await utils.getIdByCredentials(lastname, firstname, middlename)).end(); +app.get('/api/getIdByCredentials', middleware.requireToBeLoggedIn, async (req, res) => { + try { + const { lastname, firstname, middlename } = req.body; + + return res.send(await utils.getIdByCredentials(lastname, firstname, middlename)).end(); + } catch (e) { + console.log(`[ERROR] in /api/getIdByCredentials: ${e}`) + res.status(500).send(); + } +}); + + +//IN: chatId, amount +//OUT: array of objects that represent a message, like {"author_id": ..., time_sent: ..., content: ...} +//Returns an array of last ${amount} ordered by date of described objects if everything is okay +//Returns HTTP/1.1 400 "Chat with id ${ID} does not exist." if no chat with supplied id does not exist. +//Returns HTTP/1.1 403 "You are not a member of this chat" if the statement is true ;) +//Requires client to be logged in. +app.post('/api/getMessagesFromChat/by-amount', middleware.requireToBeLoggedIn, async (req, res) => { + try { + const userId = sessions[req.session.token].userId; + + const { chatId, amount } = req.body; + let messages = [] + + if ((await client.query("SELECT ID FROM Users WHERE ID = $1 AND $2 = ANY(Chats)", [userId, chatId]).rowCount == 0)) { + return res.status(403).send("You are not a member of this chat"); + } + + if ((await client.query("SELECT ID FROM Chats WHERE ID = $1", [chatId])).rowCount == 0) { + return res.status(400).send(`Chat with id ${chatId} does not exist.`).end() + } + + let result = await client.query("SELECT messages FROM Chats WHERE ID = $1 LIMIT $2", [chatId, amount]) + + let messagesIds = result.rows[0].messages; + + if (messagesIds == null || messagesIds == undefined) return res.send("").status(200).end(); + + + let selectedMessagesIds = messagesIds.slice(-amount); + + if (selectedMessagesIds == null || selectedMessagesIds == undefined) return res.send("").status(200).end(); + for (let id of selectedMessagesIds) { + let message = (await client.query("SELECT * FROM messages WHERE ID = $1 ORDER BY time_sent DESC LIMIT $2", [id, amount])).rows[0]; + messages.push(message) + } + return res.send(messages).status(200).end(); + } catch (e) { + console.log(`[ERROR] in /api/getMessagesFromChat/by-amount: ${e}`) + res.status(500).send(); + } }); //IN: chatId, fromTimestamp, toTimestamp //OUT: array of objects that represent a message, like {"author_id": ..., time_sent: ..., content: ...} //fromTimestamp must be lower that toTimestamp, otherwise it might return nothing. -//Returns an array of described objects. -//Return "Chat with id ${ID} does not exist." if no chat with supplied id does not exist. +//Returns an array of described objects if everything is okay +//Returns HTTP/1.1 400 "Chat with id ${ID} does not exist." if no chat with supplied id does not exist. +//Returns HTTP/1.1 200 and an empty string if no messages in chat are found /shrug. //Requires client to be logged in. -app.post('/api/getMessagesFromChat', middleware.requireToBeLoggedIn, async (req, res) => { - const userId = sessions[req.session.token]; +app.post('/api/getMessagesFromChat/by-time', middleware.requireToBeLoggedIn, async (req, res) => { + try { + const userId = sessions[req.session.token].userId; - const { chatId, fromTimestamp, toTimestamp } = req.body; - let messages = [] + const { chatId, fromTimestamp, toTimestamp } = req.body; + let messages = [] - if ((await client.query("SELECT ID FROM Chats WHERE ID = $1", [chatId])).rowCount == 0) { - return res.status(400).send(`Chat with id ${chatId} does not exist.`).end() + if ((await client.query("SELECT ID FROM Chats WHERE ID = $1", [chatId])).rowCount == 0) { + return res.status(400).send(`Chat with id ${chatId} does not exist.`).end() + } + + let result = await client.query("SELECT messages FROM Chats WHERE ID = $1", [chatId]) + + let messagesIds = result.rows[0].messages; + if (messagesIds == null) return res.send("").status(200).end(); + for (let id of messagesIds) { + let message = (await client.query("SELECT * FROM messages WHERE ID = $1 AND time_sent <= $2::TIMESTAMP AND time_sent >= $3::TIMESTAMP", [id, toTimestamp, fromTimestamp])).rows[0]; + if (message == undefined) continue + messages.push(message) + } + return res.send(messages).status(200).end(); + } catch (e) { + console.log(`[ERROR] in /api/getMessagesFromChat/by-time: ${e}`); + res.status(500).send(); } - - let messagesIds = (await client.query("SELECT messages FROM Chats WHERE ID = $1", [chatId])).rows[0].messages; - for (let id of messagesIds) { - let message = (await client.query("SELECT * FROM messages WHERE ID = $1 AND time_sent <= $2::TIMESTAMP AND time_sent >= $3::TIMESTAMP", [id, toTimestamp, fromTimestamp])).rows[0]; - messages.push(message) - } - return res.send(messages).status(200).end(); }); @@ -142,45 +284,101 @@ app.post('/api/getMessagesFromChat', middleware.requireToBeLoggedIn, async (req, //Returs ids of chats which user with passed ID is member in. //Return empty string if user has no membership in any chat. app.get('/api/getChats', middleware.requireToBeLoggedIn, async (req, res) => { + try { + const userId = sessions[req.session.token].userId - const userId = sessions[req.session.token] + let chats = (await client.query("SELECT chats FROM Users WHERE ID = $1", [userId])).rows[0].chats + return res.send(chats).status(200).end(); + } catch (e) { + console.log(`[ERROR] in /api/getChats: ${e}`) + res.status(500).send(); + } +}); - let chats = (await client.query("SELECT chats FROM Users WHERE ID = $1", [userId])).rows[0].chats - return res.send(chats).status(200).end(); +//IN: chatId (in route) +//OUT: JSON describes a chat with id: +//{name: ..., admins: ..., members: ...} +//Note: JSON does not include messages. You have to use /api/getMessagesFromChat to query messages. +//Returns aforementioned json if the chat exists and user is a member of this chat. +//Returns -1 if chat does not exist +//Return -2 if user is not a member of the chat +app.get('/api/getChatInfo/:chatId', middleware.requireToBeLoggedIn, async (req, res) => { + try { + const chatId = req.params.chatId; + + if (Number(chatId) != chatId) return res.send("-1").status(400).end(); + + let chatRequest = await client.query("SELECT name, admins FROM Chats WHERE ID = $1::INT", [chatId]); + if (chatRequest.rowCount == 0) return res.send("-1").status(400).end(); + + + let membersRequest = await client.query("SELECT ID FROM Users WHERE $1 = ANY(chats)", [chatId]); + + let members = []; + + membersRequest.rows.forEach((member, index, membersRequest) => { + members.push(member.id) + }); + // console.log(members) + // console.log(sessions[req.session.token]) + if (!members.includes(sessions[req.session.token].userId)) { + return res.send("-2").status(403).end(); + } + + let chatInfo = { + name: chatRequest.rows[0].name, + admins: chatRequest.rows[0].admins, + members: members + }; + + return res.send(JSON.stringify(chatInfo)).status(200).end(); + } catch (e) { + console.log(`[ERROR] in /api/getChatInfo/${req.params.chatId}: ${e}`); + res.status(500).send(); + } }); //IN: UserId, array of UserIDs that are to be invited. -//OUT: "Ok" if succsessful, "User with id ${MEMBERID} does not exist." +//OUT: "Ok" if successful, "User with id ${MEMBERID} does not exist." +//Return -1 if amout of users to invite is 0. //Requires to be logged in app.post('/api/createChat', middleware.requireToBeLoggedIn, async (req, res) => { - const userId = sessions[req.session.token] - let { toInviteIds } = req.body; + try { + const userId = sessions[req.session.token].userId + let { toInviteIds } = req.body; + if (toInviteIds == "" || toInviteIds == undefined || toInviteIds == null) return res.send("-1").status(400).end(); - toInviteIds = toInviteIds.split(" "); + toInviteIds = toInviteIds.split(" "); - toInviteIds.forEach(async (id, index, toInviteIds) => { - if ((await client.query("SELECT ID FROM Users WHERE ID = $1", [id])).rowCount == 0) { - return res.send(`User with id ${id} does not exist.`) + toInviteIds.forEach(async (id, index, toInviteIds) => { + if ((await client.query("SELECT ID FROM Users WHERE ID = $1", [id])).rowCount == 0) { + return res.send(`User with id ${id} does not exist.`).end(); + } + }); + + let chatName + if (toInviteIds.length == 1) { + let invitedFullname = (await client.query("SELECT lastname, firstname, middlename FROM Users WHERE ID = $1;", [toInviteIds[0]])).rows[0] + let invitorFullname = (await client.query("SELECT lastname, firstname, middlename FROM Users WHERE ID = $1;", [userId])).rows[0] + chatName = invitedFullname.lastname + " " + invitedFullname.firstname + " " + invitedFullname.middlename + " и " + invitorFullname.lastname + " " + invitorFullname.firstname + " " + invitorFullname.middlename + } else { + chatName = "Новая группа" } - }); - let chatName - if (toInviteIds.length == 1) { - let invitedFullname = (await client.query("SELECT lastname, firstname, middlename FROM Users WHERE ID = $1;", [toInviteIds[0]])).rows[0] - let invitorFullname = (await client.query("SELECT lastname, firstname, middlename FROM Users WHERE ID = $1;", [userId])).rows[0] - chatName = invitedFullname.lastname + " " + invitedFullname.firstname + " " + invitedFullname.middlename + " и " + invitorFullname.lastname + " " + invitorFullname.firstname + " " + invitorFullname.middlename - } else { - chatName = "Новая группа" + let chatId = (await client.query("INSERT INTO Chats (name) VALUES ($1) RETURNING ID;", [chatName])).rows[0].id + + await client.query("UPDATE Chats SET admins = ARRAY_APPEND(admins, $1) WHERE ID = $2", [userId, chatId]); + + toInviteIds.push(userId); // we need to invite the admin, too :) + toInviteIds.forEach(async (id, index, toInviteIds) => { + await client.query("UPDATE Users SET chats = ARRAY_APPEND(chats, $1) WHERE ID = $2;", [chatId, id]); + }); + + return res.send("Ok"); + } catch (e) { + console.log(`[ERROR] in /api/createChat: ${e}`); + res.status(500).send(); } - - let chatId = (await client.query("INSERT INTO Chats (name) VALUES ($1) RETURNING ID;", [chatName])).rows[0].id - - await client.query("UPDATE Chats SET admins = ARRAY_APPEND(admins, $1) WHERE ID = $2", [userId, chatId]); - - toInviteIds.forEach(async (id, index, toInviteIds) => { - await client.query("UPDATE Users SET chats = ARRAY_APPEND(chats, $1) WHERE ID = $2;", [chatId, id]); - }); - return res.send("Ok") }); //IN: none. @@ -188,9 +386,15 @@ app.post('/api/createChat', middleware.requireToBeLoggedIn, async (req, res) => //Removes client's session, thus unlogging a user. //Requires to be logged in. app.get('/api/logout', middleware.requireToBeLoggedIn, (req, res) => { - sessions[req.session.token] = undefined; - req.session.token = undefined; - res.redirect('/login'); + try { + sessions[req.session.token] = undefined; + req.session.token = undefined; + res.redirect('/login'); + } catch (e) { + console.log(`[ERROR] in /api/logout: ${e}`) + res.status(500).send(); + } + }); //IN: lastname, firstname, middlename, password. @@ -214,7 +418,10 @@ app.post('/api/register', middleware.requireToBeNotLoggedIn, async (req, res) => [lastname, firstname, middlename, hash] )).rows[0].id; req.session.token = utils.generateRandomString(); - sessions[req.session.token] = id; + sessions[req.session.token] = { + userId: id, + socket: undefined + }; res.redirect('/'); } catch (err) { console.log(`[ERROR] in /api/register: ${err}`) @@ -240,7 +447,10 @@ app.post('/api/login', middleware.requireToBeNotLoggedIn, async (req, res) => { if (bcrypt.compareSync(password, stored_password)) { req.session.token = utils.generateRandomString() - sessions[req.session.token] = ID; + sessions[req.session.token] = { + userId: ID, + socket: undefined + }; return res.redirect('/'); } else { return res.status(400).send("Wrong password").end(); @@ -249,5 +459,4 @@ app.post('/api/login', middleware.requireToBeNotLoggedIn, async (req, res) => { console.log(`[ERROR] in /api/login: ${err}`) res.status(500).send(); } - }); diff --git a/src/js/chat.js b/src/js/chat.js new file mode 100644 index 0000000..424074f --- /dev/null +++ b/src/js/chat.js @@ -0,0 +1,70 @@ +const sendMessage = (event) => { + if (event.key == "Enter") { + console.log(event); + } +} + +const createMessageElement = async (message) => { + + let author = JSON.parse(await fetch(`/api/getCredentialsById/${message.author_id}`).then(response => response.text()).then((response) => { return response; })) + + + let messageDiv = document.createElement("div"); + messageDiv.id = `message-${message.id}`; + messageDiv.style = "background-color: gray; box-shadow: 1px 1px; margin: 10px; padding: 5px" + + let authorName = document.createElement("b"); + authorName.innerText = `${author.firstname}:`; + + let messageContent = document.createElement("p"); + messageContent.innerText = message.content; + messageContent.id = "content"; + + let messageTime = document.createElement("i"); + messageTime.innerText = `@ ${message.time_sent.toString()}`; + messageTime.id = "time_sent"; + + messageDiv.appendChild(authorName); + messageDiv.appendChild(messageContent); + messageDiv.appendChild(messageTime); + + return messageDiv +} + + +window.addEventListener('load', async function () { + let location = window.location.href.split("/") + const chatId = location[location.length - 1]; + + let chatInfo = JSON.parse( + await fetch(`/api/getChatInfo/${chatId}`).then(response => response.text()).then(response => { return response }) + ); + console.log(chatInfo) + let header = document.getElementById('header-text'); + header.innerText = chatInfo.name; + let content = document.getElementById('content-div') + + + let today = new Date(); + let yesterday = new Date(); + yesterday.setUTCDate(today.getUTCDate() - 10); + console.log(today.toISOString(), yesterday.toISOString()) + // fetching messages from yesterday to today + let messages = await fetch("/api/getMessagesFromChat/by-time", { + method: "POST", + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + chatId: chatId, + fromTimestamp: yesterday.toISOString(), + toTimestamp: today.toISOString() + }) + }).then(response => response.text()).then((response) => { return response; }) + messages = eval(messages) + for (let message of messages) { + content.appendChild(await createMessageElement(message)); + } + console.log(messages) +}); \ No newline at end of file diff --git a/src/js/frontend.js b/src/js/frontend.js deleted file mode 100644 index fa9d1e8..0000000 --- a/src/js/frontend.js +++ /dev/null @@ -1,35 +0,0 @@ -let socket - -function getCookie(name) { - const value = `; ${document.cookie}`; - const parts = value.split(`; ${name}=`); - if (parts.length === 2) return parts.pop().split(';').shift(); -} - -window.addEventListener('load', function () { - let connectionString = location.protocol == "https:" ? `wss://${window.location.hostname}:${window.location.port}` : `ws://${window.location.hostname}:${window.location.port}` - socket = new WebSocket(connectionString) - console.log(getCookie("token")) - socket.addEventListener('open', (e) => { - socket.send(JSON.stringify( - { - "action": "message", - "token": getCookie("token"), - "content": { - "chatId": 1, - "text": "test" - } - } - )); - }) - - fetch("/api/getMessagesFromChat", { - method: "POST", - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ chatId: 1, fromTimestamp: '2012.01.01 00:00:00.000000', toTimestamp: '2026.01.01 00:00:00.000000' }) - }).then(response => response.text()) - .then((response => console.log(response))) -}) diff --git a/src/js/index.js b/src/js/index.js new file mode 100644 index 0000000..a9b942c --- /dev/null +++ b/src/js/index.js @@ -0,0 +1,84 @@ +let socket + +window.addEventListener('load', async function () { + let connectionString = location.protocol == "https:" ? `wss://${window.location.hostname}:${window.location.port}` : `ws://${window.location.hostname}:${window.location.port}` + socket = new WebSocket(connectionString) + socket.addEventListener('open', (e) => { + socket.send(JSON.stringify( + { + "action": "message", + "content": { + "chatId": 1, + "text": "test" + } + } + )); + }) + + socket.addEventListener('message', (m) => { + if (m.data == "successful") return; + const data = JSON.parse(m.data) + switch (data.action) { + case "message": { + console.log(`New message in chat ${data.content.chatId} from ${data.content.authorId}, which says '${data.content.text}'`) + break; + } + } + }) + + let chatsIds = await fetch("/api/getChats").then(response => response.text()).then((response) => { + return response + }) + let chats = []; // chats with their info + chatsIds = eval(chatsIds) + for (let chat of chatsIds) { + let chatInfo = await fetch(`/api/getChatInfo/${chat}`).then(response => response.text()).then(response => { return response }); + chatInfo = JSON.parse(chatInfo) + chatInfo.id = chat + let lastMessage = await fetch(`/api/getMessagesFromChat/by-amount`, { + method: "POST", + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ chatId: chat, amount: 1 }) + }).then(response => response.text()).then((response) => { return response }); + + if (lastMessage == undefined || lastMessage == "") { + chatInfo.lastMessage = { + id: "", + author_id: "", + time_sent: "", + content: "" + } + chats.push(chatInfo) + continue + } + + chatInfo.lastMessage = JSON.parse(lastMessage)[0] + chats.push(chatInfo); + } + + + let chatsContainer = this.document.getElementById('chats'); + for (let chat of chats) { + let chatHTML = ` +
+

+ ${chat.name} | ${chat.lastMessage.author_id}: ${chat.lastMessage.content} ${chat.lastMessage.time_sent} +

+
+ `; + chatsContainer.innerHTML += chatHTML; + } + + fetch("/api/getMessagesFromChat/by-time", { + method: "POST", + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ chatId: 1, fromTimestamp: '2012.01.01 00:00:00.000000', toTimestamp: '2026.01.01 00:00:00.000000' }) + }).then(response => response.text()) + // .then((response => console.log(response))) +}) diff --git a/src/utils.js b/src/utils.js index 110cd89..24a3658 100644 --- a/src/utils.js +++ b/src/utils.js @@ -6,7 +6,8 @@ const { Client } = pg; client = new Client({ user: "smk", password: "CHANGEME", // do not forget to change it in docker-compose.yml in db section. - host: "10.5.0.6", //defined in docker-compose.yml. + // host: "10.5.0.6", //defined in docker-compose.yml. + host: 'localhost', port: 5432, database: "chat" }); diff --git a/src/views/chat.html b/src/views/chat.html new file mode 100644 index 0000000..33ab24e --- /dev/null +++ b/src/views/chat.html @@ -0,0 +1,20 @@ + + + + + + Chat + + + +
+ +
+
+
+ +
+ + + + \ No newline at end of file diff --git a/src/views/index.html b/src/views/index.html index a6318f1..dc9f2dd 100644 --- a/src/views/index.html +++ b/src/views/index.html @@ -5,6 +5,9 @@ index +
+ +


@@ -13,5 +16,5 @@
Выйти - + \ No newline at end of file