125 lines
4.8 KiB
JavaScript
125 lines
4.8 KiB
JavaScript
const { Server } = require('socket.io');
|
|
const jwt = require('jsonwebtoken');
|
|
const jwtSecret = process.env.JWT_SECRET;
|
|
const { db } = require('./db.js');
|
|
|
|
function initializeSocket(server) {
|
|
const io = new Server(server, {
|
|
cookie: {
|
|
httpOnly: true,
|
|
sameSite: "strict",
|
|
maxAge: 30 * 24 * 60 * 60 * 1000
|
|
}
|
|
});
|
|
|
|
io.use((socket, next) => {
|
|
const token = socket.handshake.auth.token;
|
|
if(token) {
|
|
jwt.verify(token, jwtSecret, (err, user) => {
|
|
if(err) {
|
|
console.log(err);
|
|
return next(new Error('Authentication error'));
|
|
}
|
|
socket.user = user;
|
|
next();
|
|
});
|
|
} else {
|
|
next(new Error('Not logged in'));
|
|
}
|
|
});
|
|
|
|
io.on('connection', (socket) => {
|
|
|
|
if (!socket.user) {
|
|
console.log('User not authenticated');
|
|
socket.disconnect();
|
|
return;
|
|
}
|
|
const username = socket.user.username;
|
|
console.log(username + ' connected');
|
|
|
|
// Join a room with the user's username
|
|
socket.join(username);
|
|
|
|
|
|
// chat message event
|
|
socket.on('chat message', async (msgData) => {
|
|
const { content, recipient } = msgData;
|
|
let insertedId;
|
|
try {
|
|
// Insert the new message into the database
|
|
const result = await db.query('INSERT INTO messages (content, username, recipient) VALUES ($1, $2, $3) RETURNING id', [content, username, recipient]);
|
|
insertedId = result.rows[0].id;
|
|
} catch (err) {
|
|
console.error('Error inserting message:', err);
|
|
return;
|
|
}
|
|
|
|
// Fetch the newly inserted message from the database
|
|
try {
|
|
const query = 'SELECT id, content, username, recipient FROM messages WHERE id = $1';
|
|
const result = await db.query(query, [insertedId]);
|
|
|
|
if (result.rows.length > 0) {
|
|
const newMessage = result.rows[0];
|
|
const formattedMessage = `Username: ${newMessage.username}, recipient: ${newMessage.recipient}, message: ${newMessage.content}`;
|
|
console.log(formattedMessage);
|
|
|
|
// Emit message to the sender's and recipient's rooms
|
|
io.to(username).to(recipient).emit('chat message', { username: newMessage.username, recipient: newMessage.recipient, content: newMessage.content });
|
|
}
|
|
} catch (err) {
|
|
console.error('Error fetching inserted message:', err);
|
|
}
|
|
|
|
// i think this is not needed? (it cause duplicate messages with loading messages history)
|
|
// if (!socket.recovered) {
|
|
// try {
|
|
// const query = 'SELECT id, content, username, recipient FROM messages WHERE id > $1 ORDER BY id ASC';
|
|
// const values = [socket.handshake.auth.serverOffset || 0];
|
|
// const result = await db.query(query, values);
|
|
// //const newMessage = result.rows[0];
|
|
// for (const row of result.rows) {
|
|
// if (row.username === username || row.recipient === username) {
|
|
// io.to(username).to(recipient).emit('chat message', { username: row.username, recipient: row.recipient, content: row.content });
|
|
//
|
|
// }
|
|
// }
|
|
// } catch (e) {
|
|
// console.error('Error retrieving messages:', e);
|
|
// }
|
|
// }
|
|
});
|
|
socket.on('get messages', async (recipient) => {
|
|
const username = socket.user.username;
|
|
try {
|
|
const query = `
|
|
SELECT id, content, username, recipient
|
|
FROM messages
|
|
WHERE (username = $1 AND recipient = $2) OR (username = $2 AND recipient = $1)
|
|
ORDER BY id ASC
|
|
`;
|
|
const result = await db.query(query, [username, recipient]);
|
|
|
|
if (result.rows.length > 0) {
|
|
//const { username: sender, recipient: receiver, content: content, id: id } = result.rows;
|
|
console.log('Sending historical messages:', result.rows);
|
|
socket.emit('messages history', result.rows);
|
|
} else {
|
|
io.emit('no messages', );
|
|
}
|
|
} catch (e) {
|
|
console.error('Error retrieving messages:', e);
|
|
}
|
|
});
|
|
|
|
// disconnect event
|
|
socket.on('disconnect', () => {
|
|
console.log(username + ' has disconnected');
|
|
});
|
|
});
|
|
|
|
return io;
|
|
}
|
|
|
|
module.exports = { initializeSocket }; |