diff --git a/.env b/.env index 1c7602c..965935b 100644 --- a/.env +++ b/.env @@ -5,6 +5,6 @@ PG_PASSWORD=jebanechaslo PG_DATABASE=webchat SESSION_SECRET=changeme -JWT_SECRET=changeme +JWT_SECRET=jkldfsjklsdfjkl -APP_PORT=3000 +APP_PORT=4000 diff --git a/backend/db.js b/backend/db.js index 6039e2f..e2cefb8 100644 --- a/backend/db.js +++ b/backend/db.js @@ -1,31 +1,30 @@ -const {Client} = require('pg'); -require('dotenv').config(); +const { Client } = require("pg"); +require("dotenv").config(); -const db = new Client({ - user: process.env.PG_USER, - password: process.env.PG_PASSWORD, - database: process.env.PG_DATABASE, - host: process.env.PG_HOST, - port: process.env.PG_PORT +const db = new Client({ + user: process.env.PG_USER, + password: process.env.PG_PASSWORD, + database: process.env.PG_DATABASE, + host: process.env.PG_HOST, + port: process.env.PG_PORT, }); // create connection to database db.connect() - .then(() => { - console.log('Successfully connected to database'); - // if connection is succesful create tables - createTables() - .catch((err) => { - console.error('Error creating tables:', err); - }); - }) - .catch((err) => { - console.error('Error connecting to database: ', err); - }) + .then(() => { + console.log("Successfully connected to database"); + // if connection is successful create tables + createTables().catch((err) => { + console.error("Error creating tables:", err); + }); + }) + .catch((err) => { + console.error("Error connecting to database: ", err); + }); async function createTables() { - try { - // Create accounts table - await db.query(` + try { + // Create accounts table + await db.query(` CREATE TABLE IF NOT EXISTS accounts ( id SERIAL PRIMARY KEY, username VARCHAR(255) UNIQUE NOT NULL, @@ -33,8 +32,8 @@ async function createTables() { ) `); - // Create messages table - await db.query(` + // Create messages table + await db.query(` CREATE TABLE IF NOT EXISTS messages ( id SERIAL PRIMARY KEY, content TEXT NOT NULL, @@ -43,8 +42,8 @@ async function createTables() { ) `); - // Create contacts table - await db.query(` + // Create contacts table + await db.query(` CREATE TABLE IF NOT EXISTS contacts ( username TEXT NOT NULL, contact TEXT NOT NULL, @@ -52,59 +51,57 @@ async function createTables() { ) `); - console.log('Tables created successfully'); - } catch (err) { - console.error('Error creating tables:', err); - throw err; - } + console.log("Tables created successfully"); + } catch (err) { + console.error("Error creating tables:", err); + throw err; + } } // function for checking if user exists async function isUserExists(username) { - try { - const query = 'SELECT COUNT(*) FROM accounts WHERE username = $1'; - const result = await db.query(query, [username]); - return result.rows[0].count > 0; - } catch (err) { - console.error('Error checking username:', err); - throw err; - } + try { + const query = "SELECT COUNT(*) FROM accounts WHERE username = $1"; + const result = await db.query(query, [username]); + return result.rows[0].count > 0; + } catch (err) { + console.error("Error checking username:", err); + throw err; + } } // function for signup // function for putting user data to database -async function insertUser(username, password){ - const query = ` +async function insertUser(username, password) { + const query = ` INSERT INTO accounts (username, password) VALUES ($1, $2) RETURNING *; `; - try { - const signupData = await db.query(query, [username, password]); - console.log('Account created:', signupData.rows[0].username); - } catch (err) { - console.error('Error inserting data:', err.stack); - throw err; - } + try { + const signupData = await db.query(query, [username, password]); + console.log("Account created:", signupData.rows[0].username); + } catch (err) { + console.error("Error inserting data:", err.stack); + throw err; + } } async function changePassword(username, password) { - try { - await db.query( - 'UPDATE accounts SET password = $1 WHERE username = $2', - [password, username] - ); - } catch (err) { - console.error('Failed to update password') - throw err; - } - + try { + await db.query("UPDATE accounts SET password = $1 WHERE username = $2", [ + password, + username, + ]); + } catch (err) { + console.error("Failed to update password"); + throw err; + } } module.exports = { - db , - insertUser, - isUserExists, - changePassword + db, + insertUser, + isUserExists, + changePassword, }; - diff --git a/backend/socket.js b/backend/socket.js index f56888a..93a8b74 100644 --- a/backend/socket.js +++ b/backend/socket.js @@ -1,199 +1,220 @@ -const { Server } = require('socket.io'); -const jwt = require('jsonwebtoken'); +const { Server } = require("socket.io"); +const jwt = require("jsonwebtoken"); const jwtSecret = process.env.JWT_SECRET; -const { db } = require('./db.js'); -const {json} = require("express"); +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 + 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"); + } }); - 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 = ` + 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]); + const result = await db.query(query, [username, recipient]); - if (result.rows.length > 0) { - //const { username: sender, recipient: receiver, content: content, id: id } = result.rows; + 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)') - } - }); + 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"; + // 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 = ` + // 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 = (` + 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', () => { - return "Disconnected"; - }); + `; + 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)", + ); + } }); - return io; + 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 }; \ No newline at end of file +module.exports = { initializeSocket }; diff --git a/frontend/icons/icon.png b/frontend/icons/icon.png deleted file mode 100644 index d2d02d2..0000000 Binary files a/frontend/icons/icon.png and /dev/null differ diff --git a/frontend/js/signup.js b/frontend/js/signup.js index e0533c7..65fc1fd 100644 --- a/frontend/js/signup.js +++ b/frontend/js/signup.js @@ -1,47 +1,48 @@ window.onload = () => { - document.getElementById('username').focus(); -} + document.getElementById("username").focus(); +}; function showPasswd() { - let x = document.getElementById("password"); - let y = document.getElementById("sPassword"); - if(x.type == "password"){ - x.type = "text"; - y.type = "text"; - } else { - x.type = "password"; - y.type = "password"; - } + let x = document.getElementById("password"); + let y = document.getElementById("sPassword"); + if (x.type == "password") { + x.type = "text"; + y.type = "text"; + } else { + x.type = "password"; + y.type = "password"; + } } -document.getElementById('signupForm').addEventListener('submit',async function (event) { +document + .getElementById("signupForm") + .addEventListener("submit", async function (event) { event.preventDefault(); - const messageBox = document.getElementById('messageBox'); - const username = document.getElementById('username').value.trim(); + const messageBox = document.getElementById("messageBox"); + const username = document.getElementById("username").value.trim(); const password = document.getElementById("password").value.trim(); const sPassword = document.getElementById("sPassword").value.trim(); const jsonData = JSON.stringify({ username, password }); - if(password !== sPassword){ - messageBox.innerText = "Passwords don't match!" - return; + if (password !== sPassword) { + messageBox.innerText = "Passwords don't match!"; + return; } - - const response = await fetch ('/auth/signup', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: jsonData + const response = await fetch("/auth/signup", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: jsonData, }); - + console.log(jsonData); const result = await response.json(); - if(response.ok) { - messageBox.innerText = result.message; - messageBox.style.color = 'green'; + if (response.ok) { + messageBox.innerText = result.message; + messageBox.style.color = "green"; } else { - messageBox.innerText = result.message; - messageBox.style.color = 'red'; + messageBox.innerText = result.message; + messageBox.style.color = "red"; } -}) + }); diff --git a/frontend/routes/index.html b/frontend/routes/index.html deleted file mode 100644 index 914451a..0000000 --- a/frontend/routes/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Document - - -

LOGGED IN!!!

- - \ No newline at end of file diff --git a/index.js b/index.js index fe14820..fa53b4b 100644 --- a/index.js +++ b/index.js @@ -1,274 +1,285 @@ -require('dotenv').config(); -const express = require('express'); -const session = require('express-session'); +require("dotenv").config(); +const express = require("express"); +const session = require("express-session"); const port = process.env.APP_PORT; const app = express(); -const cookieParser = require('cookie-parser'); +const cookieParser = require("cookie-parser"); -const path = require('path'); -const { insertUser, isUserExists, changePassword, db } = require('./backend/db.js'); -const { initializeSocket } = require('./backend/socket.js'); +const path = require("path"); +const { + insertUser, + isUserExists, + changePassword, + db, +} = require("./backend/db.js"); +const { initializeSocket } = require("./backend/socket.js"); -const bcrypt = require('bcrypt'); +const bcrypt = require("bcrypt"); const saltRounds = 10; -const { createServer } = require('node:http'); +const { createServer } = require("node:http"); const server = createServer(app); -const jwt = require('jsonwebtoken'); -const {decode} = require("jsonwebtoken"); -const {json} = require("express"); +const jwt = require("jsonwebtoken"); +const { decode } = require("jsonwebtoken"); +const { json } = require("express"); const jwtSecret = process.env.JWT_SECRET; - app.use(cookieParser()); app.use(express.json()); app.use(express.urlencoded({ extended: true })); -app.use(express.static(path.join(__dirname, 'public'))); -app.use('/static', express.static('frontend')); -app.use('/socket.io', express.static('node_modules/socket.io/client-dist')); -app.use(session({ +app.use(express.static(path.join(__dirname, "public"))); +app.use("/static", express.static("frontend")); + +app.use( + session({ secret: process.env.SESSION_SECRET, resave: true, saveUninitialized: true, cookie: { - secure: false, - maxAge: 30 * 24 * 60 * 60 * 1000 //30 days - } -})); + secure: false, + maxAge: 30 * 24 * 60 * 60 * 1000, //30 days + }, + }), +); // auth login API -app.post('/auth/login', async (req, res) => { - await loginUser(req, res); +app.post("/auth/login", async (req, res) => { + await loginUser(req, res); }); // auth signup API -app.post('/auth/signup', async (req, res) => { - await signupUser(req, res); +app.post("/auth/signup", async (req, res) => { + await signupUser(req, res); }); // logout API -app.post('/auth/logout', (req, res) => { - // clear JWT token - res.clearCookie('token', { - path: '/' - }); - // clear socket.io cookie (no idea what is it for but better remove it) - res.clearCookie('io', { - path: '/' - }); - res.status(200).json({ message: 'Successfully logged out' }); +app.post("/auth/logout", (req, res) => { + // clear JWT token + res.clearCookie("token", { + path: "/", + }); + // clear socket.io cookie (no idea what is it for but better remove it) + res.clearCookie("io", { + path: "/", + }); + res.status(200).json({ message: "Successfully logged out" }); }); // get JWT token API -app.get('/auth/token', (req, res) => { - const token = req.cookies.token; - if(!token){ - res.send('Not logged in'); - } - res.send(token); +app.get("/auth/token", (req, res) => { + const token = req.cookies.token; + if (!token) { + res.send("Not logged in"); + } + res.send(token); }); -app.post('/auth/changePassword', async (req, res) => { - const token = req.cookies.token; - const { cPassword, nPassword } = req.body; +app.post("/auth/changePassword", async (req, res) => { + const token = req.cookies.token; + const { cPassword, nPassword } = req.body; - if(!cPassword && nPassword) { - return res.json({ message: 'Field is empty' }) + if (!cPassword && nPassword) { + return res.json({ message: "Field is empty" }); + } + if (nPassword === cPassword) { + return res.json({ message: "Passwords are the same" }); + } + let username; + try { + const decoded = jwt.verify(token, jwtSecret); + username = decoded.username; + } catch (err) { + return res.status(403).json({ message: "Unauthorized" }); + } + try { + const result = await db.query( + "SELECT * FROM accounts WHERE username = $1", + [username], + ); + // checks that passwords are matching + const match = await bcrypt.compare(cPassword, result.rows[0].password); + // if not return information + if (!match) { + return res.status(401).json({ message: "Current password is invalid" }); } - if(nPassword === cPassword) { - return res.json({ message: 'Passwords are the same' }) - } - let username; - try { - const decoded = jwt.verify(token, jwtSecret); - username = username = decoded.username; - } catch (err) { - return res.status(403).json({ message: 'Unauthorized'}); - } - try { - const result = await db.query('SELECT * FROM accounts WHERE username = $1', [username]); - // checks that passwords are matching - const match = await bcrypt.compare(cPassword, result.rows[0].password); - // if not return information - if(!match){ - return res.status(401).json({ message: 'Current password is invalid' }) - } - // hash password - const salt = await bcrypt.genSalt(saltRounds); - const hash = await bcrypt.hash(nPassword, salt); - await changePassword(username, hash); + // hash password + const salt = await bcrypt.genSalt(saltRounds); + const hash = await bcrypt.hash(nPassword, salt); + await changePassword(username, hash); - return res.status(200).json({ message: 'Successfully changed password' }); - } catch (err) { - return res.status(500).json({ message: 'Failed to change password' }); - } + return res.status(200).json({ message: "Successfully changed password" }); + } catch (err) { + return res.status(500).json({ message: "Failed to change password" }); + } }); // get username -app.get('/auth/user', (req, res) => { - const token = req.cookies.token; - // verify token - if(token) { - jwt.verify(token, jwtSecret, (err, user) => { - if(err) { - return res.status(403).send('Unauthorized'); - } else { - const username = user.username; - res.json({username}); - } - }); - } +app.get("/auth/user", (req, res) => { + const token = req.cookies.token; + // verify token + if (token) { + jwt.verify(token, jwtSecret, (err, user) => { + if (err) { + return res.status(403).send("Unauthorized"); + } else { + const username = user.username; + res.json({ username }); + } + }); + } }); -app.post('/api/contacts', async(req, res) => { - const token = req.cookies.token; - if(token) { - jwt.verify(token, jwtSecret, (err, user) => { - if(err) { - return res.status(403).send('Unauthorized'); - } - }); - } - const jsonContacts = JSON.stringify(req.body.contactUsername); +app.post("/api/contacts", async (req, res) => { + const token = req.cookies.token; + if (token) { + jwt.verify(token, jwtSecret, (err, user) => { + if (err) { + return res.status(403).send("Unauthorized"); + } + }); + } + const jsonContacts = JSON.stringify(req.body.contactUsername); }); // serving the login page -app.get('/login', (req, res) => { - const token = req.cookies.token; - // verify token - if (token) { - res.json({ Error: 'Already logged in' }); - } else { - res.sendFile(path.join(__dirname, '/frontend/routes/login.html')); - } +app.get("/login", (req, res) => { + const token = req.cookies.token; + // verify token + if (token) { + res.json({ Error: "Already logged in" }); + } else { + res.sendFile(path.join(__dirname, "/frontend/routes/login.html")); + } }); // serving the signup page -app.get('/signup', (req, res) => { - const token = req.cookies.token; - if(token){ - res.json({ Error: 'Already logged in' }); - } else - res.sendFile(path.join(__dirname, '/frontend/routes/signup.html')); +app.get("/signup", (req, res) => { + const token = req.cookies.token; + if (token) { + res.json({ Error: "Already logged in" }); + } else res.sendFile(path.join(__dirname, "/frontend/routes/signup.html")); }); -app.get('/settings', (req, res) => { - const token = req.cookies.token; +app.get("/settings", (req, res) => { + const token = req.cookies.token; - if(!token) { - res.redirect('/login'); - return; + if (!token) { + res.redirect("/login"); + return; + } + // verify token + jwt.verify(token, jwtSecret, (err) => { + if (err) { + return res.status(403).send("Unauthorized"); } - // verify token - jwt.verify(token, jwtSecret, (err) => { - if (err) { - return res.status(403).send('Unauthorized'); - } - res.sendFile(path.join(__dirname, '/frontend/routes/settings.html')) - }); -}) + res.sendFile(path.join(__dirname, "/frontend/routes/settings.html")); + }); +}); -app.get('/', (req, res) => { - const token = req.cookies.token; +app.get("/", (req, res) => { + const token = req.cookies.token; - if(!token) { - return res.redirect('/login'); - - } else { - return res.redirect('/chat'); - } -}) + if (!token) { + return res.redirect("/login"); + } else { + return res.redirect("/chat"); + } +}); // serving the chat page if logged in -app.get('/chat', (req, res) => { - const token = req.cookies.token; +app.get("/chat", (req, res) => { + const token = req.cookies.token; - if(!token) { - res.redirect('/login'); - return; + if (!token) { + res.redirect("/login"); + return; + } + // verify token + jwt.verify(token, jwtSecret, (err) => { + if (err) { + return res.status(403).send("Unauthorized"); } - // verify token - jwt.verify(token, jwtSecret, (err) => { - if (err) { - return res.status(403).send('Unauthorized'); - } - res.sendFile(path.join(__dirname, '/frontend/routes/chat.html')); - }); + res.sendFile(path.join(__dirname, "/frontend/routes/chat.html")); + }); }); -initializeSocket(server) +initializeSocket(server); // run server server.listen(port, () => { - console.log(`Chat app listening on port ${port}`); + console.log(`Chat app listening on port ${port}`); }); // signup function async function signupUser(req, res) { - let username = req.body.username; - let password = req.body.password; + let username = req.body.username; + let password = req.body.password; - if(username && password){ - try { - // Check if user exists - const exists = await isUserExists(username); - if (exists) { - console.log('User already exists'); - return res.status(500).json({ message: 'User already exists!' }); - } + if (username && password) { + try { + // Check if user exists + const exists = await isUserExists(username); + if (exists) { + console.log("User already exists"); + return res.status(500).json({ message: "User already exists!" }); + } - // Hash password - const salt = await bcrypt.genSalt(saltRounds); - const hash = await bcrypt.hash(password, salt); + // Hash password + const salt = await bcrypt.genSalt(saltRounds); + const hash = await bcrypt.hash(password, salt); - // Insert user - await insertUser(username, hash); - return res.status(200).json({ message: "Account successfully created" }); - } catch (err) { - console.error('Error inserting data:', err); - return res.status(500).json({ message: 'Error inserting data' }); - } - } else { - res.status(400).json({ message: 'Form is empty'}) + // Insert user + await insertUser(username, hash); + return res.status(200).json({ message: "Account successfully created" }); + } catch (err) { + console.error("Error inserting data:", err); + return res.status(500).json({ message: "Error inserting data" }); } + } else { + res.status(400).json({ message: "Form is empty" }); + } } // login function async function loginUser(req, res) { + let username = req.body.username; + let password = req.body.password; - let username = req.body.username; - let password = req.body.password; + if (username && password) { + try { + username = username.trim(); + password = password.trim(); - if (username && password) { - try { - username = username.trim(); - password = password.trim(); - - const result = await db.query('SELECT * FROM accounts WHERE username = $1', [username]); - // check if user exists - if (result.rows.length > 0) { - // Compare password - const match = await bcrypt.compare(password, result.rows[0].password); - if (!match) { - res.status(401).json({ message: 'Invalid password'}); - return; - } - const token = jwt.sign({ username }, jwtSecret, { - expiresIn: '30d' // token expires in 30 days - }); - res.cookie('token', token, { - httpOnly: true, - maxAge: 30 * 24 * 60 * 60 * 1000 // 30 days - }); - req.session.loggedin = true; - req.session.username = username; - res.status(200).json({ message: 'Successfully logged in' }); - } else { - return res.status(401).json({ message: 'Incorrect Username or Password!'}) - } - } catch (error) { - console.error('Error executing query', error); - res.status(500).json({ message: 'Internal server error' }); + const result = await db.query( + "SELECT * FROM accounts WHERE username = $1", + [username], + ); + // check if user exists + if (result.rows.length > 0) { + // Compare password + const match = await bcrypt.compare(password, result.rows[0].password); + if (!match) { + res.status(401).json({ message: "Invalid password" }); + return; } - } else { - res.status(400).json({ message: 'Please enter Username and Password!' }); + const token = jwt.sign({ username }, jwtSecret, { + expiresIn: "30d", // token expires in 30 days + }); + res.cookie("token", token, { + httpOnly: true, + maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days + }); + req.session.loggedin = true; + req.session.username = username; + res.status(200).json({ message: "Successfully logged in" }); + } else { + return res + .status(401) + .json({ message: "Incorrect Username or Password!" }); + } + } catch (error) { + console.error("Error executing query", error); + res.status(500).json({ message: "Internal server error" }); } - res.end(); -} \ No newline at end of file + } else { + res.status(400).json({ message: "Please enter Username and Password!" }); + } + res.end(); +}