From aea8ad22d1fb6f3968297425ba6022cd2f79fa1d Mon Sep 17 00:00:00 2001 From: mrfry Date: Sat, 29 May 2021 21:44:48 +0200 Subject: [PATCH] Chat --- src/middlewares/auth.middleware.ts | 2 +- src/middlewares/socketAuth.middleware.ts | 48 +++++---- src/modules/api/msgsDbStruct.json | 8 ++ src/modules/api/submodules/chat.ts | 123 ++++++++++++++--------- src/utils/utils.ts | 1 - submodules/qmining-page | 2 +- 6 files changed, 115 insertions(+), 69 deletions(-) diff --git a/src/middlewares/auth.middleware.ts b/src/middlewares/auth.middleware.ts index 4f8ee5e..fcb8260 100644 --- a/src/middlewares/auth.middleware.ts +++ b/src/middlewares/auth.middleware.ts @@ -8,7 +8,7 @@ interface Options { exceptions: Array } -const testUser = { +export const testUser = { id: 19, avaiblePWRequests: 645, pwRequestCount: 19, diff --git a/src/middlewares/socketAuth.middleware.ts b/src/middlewares/socketAuth.middleware.ts index d55b6f0..7a9752c 100644 --- a/src/middlewares/socketAuth.middleware.ts +++ b/src/middlewares/socketAuth.middleware.ts @@ -2,34 +2,44 @@ import logger from '../utils/logger' import dbtools from '../utils/dbtools' import cookie from 'cookie' +import { testUser } from './auth.middleware' + interface Options { userDB: any } -export default function (options: Options): any { +export default function SocketAuth(options: Options): any { const { userDB } = options - return function (socket, next) { - const cookies = cookie.parse(socket.handshake.headers.cookie) - const sessionID = cookies.sessionID + return (socket, next) => { + try { + const cookies = cookie.parse(socket.handshake.headers.cookie || '') + const sessionID = cookies.sessionID - if (process.env.NS_NOUSER) { + if (process.env.NS_NOUSER) { + socket.user = testUser + next() + return + } + + if (!sessionID) { + next(new Error('Not authenticated, please log in')) + return + } + + const user = GetUserBySessionID(userDB, sessionID) + + if (!user) { + next(new Error('Not authenticated, please log in')) + return + } + socket.user = user next() - return + } catch (e) { + next(new Error('Authentication server error')) + console.error('Authentication server error') + console.error(e) } - - if (!sessionID) { - next(new Error('Authentication error')) - return - } - - const user = GetUserBySessionID(userDB, sessionID) - - if (!user) { - next(new Error('Authentication error')) - return - } - next() } } diff --git a/src/modules/api/msgsDbStruct.json b/src/modules/api/msgsDbStruct.json index d34255c..a1f39ba 100644 --- a/src/modules/api/msgsDbStruct.json +++ b/src/modules/api/msgsDbStruct.json @@ -1,6 +1,11 @@ { "msgs": { "tableStruct": { + "id": { + "type": "integer", + "primary": true, + "autoIncrement": true + }, "sender": { "type": "integer", "notNull": true @@ -12,6 +17,9 @@ "msg": { "type": "text" }, + "type": { + "type": "text" + }, "date": { "type": "integer" }, diff --git a/src/modules/api/submodules/chat.ts b/src/modules/api/submodules/chat.ts index c642441..7de508d 100644 --- a/src/modules/api/submodules/chat.ts +++ b/src/modules/api/submodules/chat.ts @@ -1,16 +1,24 @@ -import { Server as socket } from 'socket.io' +import { Server as socket, Socket } from 'socket.io' +import utils from '../../../utils/utils' import dbtools from '../../../utils/dbtools' import logger from '../../../utils/logger' -import { Request, SubmoduleData } from '../../../types/basicTypes' +import { Request, SubmoduleData, User } from '../../../types/basicTypes' import socketAuth from '../../../middlewares/socketAuth.middleware' const msgDbPath = './data/dbs/msgs.db' +const msgPaginationLimit = 15 + +interface ExtendedSocket extends Socket { + user: User +} function setup(data: SubmoduleData): void { - const { app, httpServer, httpsServer, userDB } = data + const { app, httpServer, httpsServer, userDB, publicdirs } = data const msgDB = dbtools.GetDB(msgDbPath) + const publicDir = publicdirs[0] + const uloadFiles = publicDir + 'chatFiles' logger.Log(`Starting Socket.io Server on ${httpsServer ? 'https' : 'http'}`) // https://socket.io/docs/v4/handling-cors/#Configuration const io = new socket(httpsServer || httpServer, { @@ -29,29 +37,28 @@ function setup(data: SubmoduleData): void { where sender = ${sender} and reciever = ${reciever}`, 'run' ) - io.sockets.in(sender).emit('chat message read', { + io.sockets.in(sender.toString()).emit('chat message read', { userReadMsg: reciever, }) } io.use(socketAuth({ userDB: userDB })) - io.on('connection', (socket) => { - // TODO - // https://stackoverflow.com/questions/19106861/authorizing-and-handshaking-with-socket-io#19106961 - // socket.handshake.headers - // if (data.id !== user.id) { - // socket.disconnect() - // socket.emit('connectData', { - // success: false, - // msg: `You are only authorized to connect as ${user.id}!` - // }) - // return - // } + io.on('connection', (socket: ExtendedSocket) => { + // TODO: UNCOMMENT + // ----------------------------------------------------------------- + // const userid = socket.user.id + // logger.Log(`Chat connect: ${userid}`, logger.GetColor('green')) + // ----------------------------------------------------------------- socket.on('join', function (data) { - socket.join(data.id) - const userid = data.id + // TODO: REMOVE + // ----------------------------------------------------------------- + const userid = parseInt(data.id) + logger.Log(`Chat connect: ${userid}`, logger.GetColor('green')) + // ----------------------------------------------------------------- + + socket.join(userid.toString()) let currUser = dbtools.Select(msgDB, 'users', { id: userid, })[0] @@ -66,16 +73,16 @@ function setup(data: SubmoduleData): void { .runStatement( msgDB, `select * from - ( - select sender as a - from msgs - where sender = ${userid} or reciever = ${userid} - union - select reciever - from msgs - where sender = ${userid} or reciever = ${userid} - )t - order by t.a asc` + ( + select sender as a + from msgs + where sender = ${userid} or reciever = ${userid} + union + select reciever + from msgs + where sender = ${userid} or reciever = ${userid} + )t + order by t.a asc` ) .reduce((acc, x) => { if (x.a !== userid) acc.push(x.a) @@ -87,30 +94,33 @@ function setup(data: SubmoduleData): void { const first = dbtools.runStatement( msgDB, `select * from msgs - where sender = ${userid} and reciever = ${to} or - sender = ${to} and reciever = ${userid} - order by date desc - limit 1` + where sender = ${userid} and reciever = ${to} or + sender = ${to} and reciever = ${userid} + order by date desc + limit 1` )[0] return first }), }) - socket.on('chat message open', (data) => { - const { chatPartner } = data + socket.on('get chat messages', (data) => { + const { chatPartner, from } = data - // TODO: pagination - socket.emit( - 'chat message open', - dbtools.runStatement( - msgDB, - `select * from msgs - where sender = ${userid} and reciever = ${chatPartner} or - sender = ${chatPartner} and reciever = ${userid} - order by date asc` - ) + const msgs = dbtools.runStatement( + msgDB, + `select * from msgs + where (sender = ${userid} and reciever = ${chatPartner} or + sender = ${chatPartner} and reciever = ${userid}) + ${from ? `and date < ${from}` : ''} + order by date desc + limit ${msgPaginationLimit}` ) + socket.emit('get chat messages', { + requestsdMsgs: msgs, + hasMore: msgs.length === msgPaginationLimit, + }) + // Read update chatMessageRead({ sender: chatPartner, reciever: userid }) }) @@ -121,7 +131,7 @@ function setup(data: SubmoduleData): void { }) socket.on('chat message', (message) => { - const { reciever, msg } = message + const { reciever, msg, type } = message const recieverUser = dbtools.Select(msgDB, 'users', { id: reciever, })[0] @@ -131,26 +141,45 @@ function setup(data: SubmoduleData): void { date: new Date().getTime(), sender: reciever, reciever: userid, + type: 'text', msg: `A #${reciever} számú felhasználó nem létezik`, }) return } const msgObj = { - sender: parseInt(userid), + sender: userid, reciever: parseInt(reciever), msg: msg, + type: type || 'text', date: new Date().getTime(), unread: 1, } dbtools.Insert(msgDB, 'msgs', msgObj) if (userid !== reciever) { - io.sockets.in(reciever).emit('chat message', msgObj) + io.sockets.in(reciever.toString()).emit('chat message', msgObj) } }) }) // socket.on('disconnect', () => {}) + // socket.on('close', () => {}) + }) + + app.post('/postchatfile', function (req: Request, res: any) { + logger.LogReq(req) + utils + .uploadFile(req, uloadFiles) + .then((result) => { + res.json({ + success: true, + path: result.filePath.replace(publicDir, ''), + }) + }) + .catch(() => { + res.json({ success: false, msg: 'error during uploading' }) + return + }) }) app.get('/hasNewMsg', (req: Request, res) => { diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 30b697c..cb14115 100755 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -206,7 +206,6 @@ function uploadFile(req: Request, path: string): Promise { const temp = file.name.split('.') const extension = temp.pop() fileName = temp.join('.') + '_' + id + '.' + extension - console.log(fileName) fileDestination = path + '/' + fileName } diff --git a/submodules/qmining-page b/submodules/qmining-page index c60ace4..602e160 160000 --- a/submodules/qmining-page +++ b/submodules/qmining-page @@ -1 +1 @@ -Subproject commit c60ace4f9b9b7a0f45963c226b809d0b8b6bab29 +Subproject commit 602e16046e6600a405ae68814c11349fde745244