Deleted obsolete files, including icon.png and index.html. Refactored JavaScript code in signup.js and socket.js for better readability by adjusting indentation and format. Updated environment variables in .env and streamlined several routes and functions in index.js.
221 lines
6.8 KiB
JavaScript
221 lines
6.8 KiB
JavaScript
const { Server } = require("socket.io");
|
|
const jwt = require("jsonwebtoken");
|
|
const jwtSecret = process.env.JWT_SECRET;
|
|
const { db } = require("./db.js");
|
|
const { json } = require("express");
|
|
|
|
function initializeSocket(server) {
|
|
const io = new Server(server, {
|
|
cookie: {
|
|
httpOnly: true,
|
|
sameSite: "strict",
|
|
maxAge: 30 * 24 * 60 * 60 * 1000,
|
|
},
|
|
});
|
|
|
|
io.use((socket, next) => {
|
|
// user auth
|
|
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"));
|
|
}
|
|
});
|
|
|
|
// open main socket connection
|
|
io.on("connection", (socket) => {
|
|
if (!socket.user) {
|
|
socket.emit("socket error", "User not authenticated");
|
|
socket.disconnect();
|
|
return;
|
|
}
|
|
const username = socket.user.username;
|
|
// Join a room with the user's username
|
|
socket.join(username);
|
|
|
|
io.to(username).emit("username", 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);
|
|
socket.emit(
|
|
"socket error",
|
|
"Error inserting message, try refreshing the page",
|
|
);
|
|
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];
|
|
|
|
// 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);
|
|
socket.emit("socket error", "Failed to send message");
|
|
}
|
|
});
|
|
|
|
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;
|
|
|
|
io.to(username).emit("messages history", result.rows);
|
|
} else {
|
|
io.to(username).emit("no messages");
|
|
}
|
|
} catch (e) {
|
|
console.error("Error retrieving messages:", e);
|
|
socket.emit(
|
|
"socket error",
|
|
"Error retrieving messages, refresh the page (server error)",
|
|
);
|
|
}
|
|
});
|
|
|
|
// Contacts socket
|
|
socket.on("contacts", async (contactUsername) => {
|
|
const username = socket.user.username;
|
|
const status = contactUsername.status === "read" ? "read" : "unread";
|
|
|
|
// Update contact list in db
|
|
try {
|
|
const query = `
|
|
INSERT INTO contacts (username, contact, status)
|
|
SELECT $1, $2, $3
|
|
WHERE NOT EXISTS (
|
|
SELECT 1 FROM contacts WHERE username = $1 AND contact = $2
|
|
)
|
|
`;
|
|
await db.query(query, [username, contactUsername.contact, status]);
|
|
} catch (err) {
|
|
console.error("Failed to update contacts ", err);
|
|
socket.emit("socket error", "Failed to update contacts (server error)");
|
|
}
|
|
// Get contact list from db
|
|
try {
|
|
const query = `
|
|
SELECT contact, username, status
|
|
FROM contacts
|
|
WHERE username = $1
|
|
`;
|
|
const result = await db.query(query, [username]);
|
|
io.to(username).emit("contacts", result.rows);
|
|
} catch (err) {
|
|
console.error("Failed to get contacts from db");
|
|
io.to(username).emit(
|
|
"socket error",
|
|
"Failed to get contacts (server error)",
|
|
);
|
|
}
|
|
});
|
|
|
|
socket.on("get contacts", async () => {
|
|
const username = socket.user.username;
|
|
try {
|
|
const query = `
|
|
SELECT contact, username, status
|
|
FROM contacts
|
|
WHERE username = $1
|
|
`;
|
|
const result = await db.query(query, [username]);
|
|
io.to(username).emit("contacts", result.rows);
|
|
} catch (err) {
|
|
console.error("Failed to get contacts from db");
|
|
io.to(username).emit(
|
|
"socket error",
|
|
"Failed to get contacts (server error)",
|
|
);
|
|
}
|
|
});
|
|
socket.on("delete contact", async (contactUsername) => {
|
|
const username = socket.user.username;
|
|
try {
|
|
const query =
|
|
"DELETE FROM contacts WHERE (username = $1 AND contact = $2)";
|
|
await db.query(query, [username, contactUsername]);
|
|
} catch (err) {
|
|
console.error("Failed to remove contact from db");
|
|
io.to(username).emit(
|
|
"socket error",
|
|
"Failed to remove contact (server error)",
|
|
);
|
|
}
|
|
});
|
|
|
|
socket.on("status", async (username) => {
|
|
const userUsername = socket.user.username;
|
|
const status = "unread";
|
|
try {
|
|
const query =
|
|
"UPDATE contacts SET status = $1 WHERE username = $2 AND contact = $3";
|
|
await db.query(query, [status, userUsername, username]);
|
|
io.to(userUsername).emit("status", username);
|
|
} catch (err) {
|
|
console.error("Failed to update unread status:", err);
|
|
}
|
|
});
|
|
|
|
socket.on("read", async (contactUsername) => {
|
|
const userUsername = socket.user.username;
|
|
const status = "read";
|
|
try {
|
|
const query =
|
|
"UPDATE contacts SET status = $1 WHERE username = $2 AND contact = $3";
|
|
await db.query(query, [status, userUsername, contactUsername]);
|
|
io.to(userUsername).emit("status", contactUsername);
|
|
} catch (err) {
|
|
console.error("Failed to update unread status:", err);
|
|
}
|
|
});
|
|
// disconnect event
|
|
socket.on("disconnect", () => {
|
|
console.log(socket.id, " disconnected");
|
|
return "Disconnected";
|
|
});
|
|
});
|
|
|
|
return io;
|
|
}
|
|
|
|
module.exports = { initializeSocket };
|