Remove unused files and improve code clarity
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.
This commit is contained in:
4
.env
4
.env
@@ -5,6 +5,6 @@ PG_PASSWORD=jebanechaslo
|
|||||||
PG_DATABASE=webchat
|
PG_DATABASE=webchat
|
||||||
|
|
||||||
SESSION_SECRET=changeme
|
SESSION_SECRET=changeme
|
||||||
JWT_SECRET=changeme
|
JWT_SECRET=jkldfsjklsdfjkl
|
||||||
|
|
||||||
APP_PORT=3000
|
APP_PORT=4000
|
||||||
|
|||||||
@@ -1,27 +1,26 @@
|
|||||||
const {Client} = require('pg');
|
const { Client } = require("pg");
|
||||||
require('dotenv').config();
|
require("dotenv").config();
|
||||||
|
|
||||||
const db = new Client({
|
const db = new Client({
|
||||||
user: process.env.PG_USER,
|
user: process.env.PG_USER,
|
||||||
password: process.env.PG_PASSWORD,
|
password: process.env.PG_PASSWORD,
|
||||||
database: process.env.PG_DATABASE,
|
database: process.env.PG_DATABASE,
|
||||||
host: process.env.PG_HOST,
|
host: process.env.PG_HOST,
|
||||||
port: process.env.PG_PORT
|
port: process.env.PG_PORT,
|
||||||
});
|
});
|
||||||
|
|
||||||
// create connection to database
|
// create connection to database
|
||||||
db.connect()
|
db.connect()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log('Successfully connected to database');
|
console.log("Successfully connected to database");
|
||||||
// if connection is succesful create tables
|
// if connection is successful create tables
|
||||||
createTables()
|
createTables().catch((err) => {
|
||||||
.catch((err) => {
|
console.error("Error creating tables:", err);
|
||||||
console.error('Error creating tables:', err);
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error('Error connecting to database: ', err);
|
console.error("Error connecting to database: ", err);
|
||||||
})
|
});
|
||||||
async function createTables() {
|
async function createTables() {
|
||||||
try {
|
try {
|
||||||
// Create accounts table
|
// Create accounts table
|
||||||
@@ -52,9 +51,9 @@ async function createTables() {
|
|||||||
)
|
)
|
||||||
`);
|
`);
|
||||||
|
|
||||||
console.log('Tables created successfully');
|
console.log("Tables created successfully");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error creating tables:', err);
|
console.error("Error creating tables:", err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,11 +61,11 @@ async function createTables() {
|
|||||||
// function for checking if user exists
|
// function for checking if user exists
|
||||||
async function isUserExists(username) {
|
async function isUserExists(username) {
|
||||||
try {
|
try {
|
||||||
const query = 'SELECT COUNT(*) FROM accounts WHERE username = $1';
|
const query = "SELECT COUNT(*) FROM accounts WHERE username = $1";
|
||||||
const result = await db.query(query, [username]);
|
const result = await db.query(query, [username]);
|
||||||
return result.rows[0].count > 0;
|
return result.rows[0].count > 0;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error checking username:', err);
|
console.error("Error checking username:", err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,29 +81,27 @@ async function insertUser(username, password){
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const signupData = await db.query(query, [username, password]);
|
const signupData = await db.query(query, [username, password]);
|
||||||
console.log('Account created:', signupData.rows[0].username);
|
console.log("Account created:", signupData.rows[0].username);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error inserting data:', err.stack);
|
console.error("Error inserting data:", err.stack);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function changePassword(username, password) {
|
async function changePassword(username, password) {
|
||||||
try {
|
try {
|
||||||
await db.query(
|
await db.query("UPDATE accounts SET password = $1 WHERE username = $2", [
|
||||||
'UPDATE accounts SET password = $1 WHERE username = $2',
|
password,
|
||||||
[password, username]
|
username,
|
||||||
);
|
]);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to update password')
|
console.error("Failed to update password");
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
module.exports = {
|
module.exports = {
|
||||||
db,
|
db,
|
||||||
insertUser,
|
insertUser,
|
||||||
isUserExists,
|
isUserExists,
|
||||||
changePassword
|
changePassword,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const { Server } = require('socket.io');
|
const { Server } = require("socket.io");
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require("jsonwebtoken");
|
||||||
const jwtSecret = process.env.JWT_SECRET;
|
const jwtSecret = process.env.JWT_SECRET;
|
||||||
const { db } = require('./db.js');
|
const { db } = require("./db.js");
|
||||||
const { json } = require("express");
|
const { json } = require("express");
|
||||||
|
|
||||||
function initializeSocket(server) {
|
function initializeSocket(server) {
|
||||||
@@ -9,8 +9,8 @@ function initializeSocket(server) {
|
|||||||
cookie: {
|
cookie: {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
sameSite: "strict",
|
sameSite: "strict",
|
||||||
maxAge: 30 * 24 * 60 * 60 * 1000
|
maxAge: 30 * 24 * 60 * 60 * 1000,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
io.use((socket, next) => {
|
io.use((socket, next) => {
|
||||||
@@ -20,20 +20,20 @@ function initializeSocket(server) {
|
|||||||
jwt.verify(token, jwtSecret, (err, user) => {
|
jwt.verify(token, jwtSecret, (err, user) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
return next(new Error('Authentication error'));
|
return next(new Error("Authentication error"));
|
||||||
}
|
}
|
||||||
socket.user = user;
|
socket.user = user;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
next(new Error('Not logged in'));
|
next(new Error("Not logged in"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// open main socket connection
|
// open main socket connection
|
||||||
io.on('connection', (socket) => {
|
io.on("connection", (socket) => {
|
||||||
if (!socket.user) {
|
if (!socket.user) {
|
||||||
socket.emit('socket error', 'User not authenticated')
|
socket.emit("socket error", "User not authenticated");
|
||||||
socket.disconnect();
|
socket.disconnect();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -41,41 +41,51 @@ function initializeSocket(server) {
|
|||||||
// Join a room with the user's username
|
// Join a room with the user's username
|
||||||
socket.join(username);
|
socket.join(username);
|
||||||
|
|
||||||
io.to(username).emit('username', username);
|
io.to(username).emit("username", username);
|
||||||
|
|
||||||
// chat message event
|
// chat message event
|
||||||
socket.on('chat message', async (msgData) => {
|
socket.on("chat message", async (msgData) => {
|
||||||
const { content, recipient } = msgData;
|
const { content, recipient } = msgData;
|
||||||
let insertedId;
|
let insertedId;
|
||||||
try {
|
try {
|
||||||
// Insert the new message into the database
|
// 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]);
|
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;
|
insertedId = result.rows[0].id;
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error inserting message:', err);
|
console.error("Error inserting message:", err);
|
||||||
socket.emit('socket error', "Error inserting message, try refreshing the page")
|
socket.emit(
|
||||||
|
"socket error",
|
||||||
|
"Error inserting message, try refreshing the page",
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch the newly inserted message from the database
|
// Fetch the newly inserted message from the database
|
||||||
try {
|
try {
|
||||||
const query = 'SELECT id, content, username, recipient FROM messages WHERE id = $1';
|
const query =
|
||||||
|
"SELECT id, content, username, recipient FROM messages WHERE id = $1";
|
||||||
const result = await db.query(query, [insertedId]);
|
const result = await db.query(query, [insertedId]);
|
||||||
|
|
||||||
if (result.rows.length > 0) {
|
if (result.rows.length > 0) {
|
||||||
const newMessage = result.rows[0];
|
const newMessage = result.rows[0];
|
||||||
|
|
||||||
// Emit message to the sender's and recipient's rooms
|
// 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 });
|
io.to(username).to(recipient).emit("chat message", {
|
||||||
|
username: newMessage.username,
|
||||||
|
recipient: newMessage.recipient,
|
||||||
|
content: newMessage.content,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error fetching inserted message:', err);
|
console.error("Error fetching inserted message:", err);
|
||||||
socket.emit('socket error', 'Failed to send message')
|
socket.emit("socket error", "Failed to send message");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('get messages', async (recipient) => {
|
socket.on("get messages", async (recipient) => {
|
||||||
const username = socket.user.username;
|
const username = socket.user.username;
|
||||||
try {
|
try {
|
||||||
const query = `
|
const query = `
|
||||||
@@ -89,20 +99,23 @@ function initializeSocket(server) {
|
|||||||
if (result.rows.length > 0) {
|
if (result.rows.length > 0) {
|
||||||
//const { username: sender, recipient: receiver, content: content, id: id } = result.rows;
|
//const { username: sender, recipient: receiver, content: content, id: id } = result.rows;
|
||||||
|
|
||||||
io.to(username).emit('messages history', result.rows);
|
io.to(username).emit("messages history", result.rows);
|
||||||
} else {
|
} else {
|
||||||
io.to(username).emit('no messages');
|
io.to(username).emit("no messages");
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error retrieving messages:', e);
|
console.error("Error retrieving messages:", e);
|
||||||
socket.emit('socket error', 'Error retrieving messages, refresh the page (server error)')
|
socket.emit(
|
||||||
|
"socket error",
|
||||||
|
"Error retrieving messages, refresh the page (server error)",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Contacts socket
|
// Contacts socket
|
||||||
socket.on('contacts', async (contactUsername) => {
|
socket.on("contacts", async (contactUsername) => {
|
||||||
const username = socket.user.username;
|
const username = socket.user.username;
|
||||||
const status = (contactUsername.status === "read") ? "read" : "unread";
|
const status = contactUsername.status === "read" ? "read" : "unread";
|
||||||
|
|
||||||
// Update contact list in db
|
// Update contact list in db
|
||||||
try {
|
try {
|
||||||
@@ -115,80 +128,88 @@ function initializeSocket(server) {
|
|||||||
`;
|
`;
|
||||||
await db.query(query, [username, contactUsername.contact, status]);
|
await db.query(query, [username, contactUsername.contact, status]);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to update contacts ', err)
|
console.error("Failed to update contacts ", err);
|
||||||
socket.emit('socket error', 'Failed to update contacts (server error)')
|
socket.emit("socket error", "Failed to update contacts (server error)");
|
||||||
}
|
}
|
||||||
// Get contact list from db
|
// Get contact list from db
|
||||||
try {
|
try {
|
||||||
const query = (`
|
const query = `
|
||||||
SELECT contact, username, status
|
SELECT contact, username, status
|
||||||
FROM contacts
|
FROM contacts
|
||||||
WHERE username = $1
|
WHERE username = $1
|
||||||
`);
|
`;
|
||||||
const result = await db.query(query, [username]);
|
const result = await db.query(query, [username]);
|
||||||
io.to(username).emit('contacts', result.rows);
|
io.to(username).emit("contacts", result.rows);
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to get contacts from db');
|
console.error("Failed to get contacts from db");
|
||||||
io.to(username).emit('socket error', 'Failed to get contacts (server error)');
|
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) => {
|
socket.on("get contacts", async () => {
|
||||||
const userUsername = socket.user.username;
|
const username = socket.user.username;
|
||||||
const status = 'read';
|
|
||||||
try {
|
try {
|
||||||
const query = ('UPDATE contacts SET status = $1 WHERE username = $2 AND contact = $3');
|
const query = `
|
||||||
await db.query(query, [status, userUsername, contactUsername]);
|
SELECT contact, username, status
|
||||||
io.to(userUsername).emit('status', contactUsername);
|
FROM contacts
|
||||||
|
WHERE username = $1
|
||||||
|
`;
|
||||||
|
const result = await db.query(query, [username]);
|
||||||
|
io.to(username).emit("contacts", result.rows);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to update unread status:', 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
|
// disconnect event
|
||||||
socket.on('disconnect', () => {
|
socket.on("disconnect", () => {
|
||||||
|
console.log(socket.id, " disconnected");
|
||||||
return "Disconnected";
|
return "Disconnected";
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1009 B |
@@ -1,6 +1,6 @@
|
|||||||
window.onload = () => {
|
window.onload = () => {
|
||||||
document.getElementById('username').focus();
|
document.getElementById("username").focus();
|
||||||
}
|
};
|
||||||
|
|
||||||
function showPasswd() {
|
function showPasswd() {
|
||||||
let x = document.getElementById("password");
|
let x = document.getElementById("password");
|
||||||
@@ -14,34 +14,35 @@ function showPasswd() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('signupForm').addEventListener('submit',async function (event) {
|
document
|
||||||
|
.getElementById("signupForm")
|
||||||
|
.addEventListener("submit", async function (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const messageBox = document.getElementById('messageBox');
|
const messageBox = document.getElementById("messageBox");
|
||||||
const username = document.getElementById('username').value.trim();
|
const username = document.getElementById("username").value.trim();
|
||||||
const password = document.getElementById("password").value.trim();
|
const password = document.getElementById("password").value.trim();
|
||||||
const sPassword = document.getElementById("sPassword").value.trim();
|
const sPassword = document.getElementById("sPassword").value.trim();
|
||||||
const jsonData = JSON.stringify({ username, password });
|
const jsonData = JSON.stringify({ username, password });
|
||||||
|
|
||||||
if (password !== sPassword) {
|
if (password !== sPassword) {
|
||||||
messageBox.innerText = "Passwords don't match!"
|
messageBox.innerText = "Passwords don't match!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const response = await fetch("/auth/signup", {
|
||||||
const response = await fetch ('/auth/signup', {
|
method: "POST",
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: jsonData
|
body: jsonData,
|
||||||
});
|
});
|
||||||
|
console.log(jsonData);
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
messageBox.innerText = result.message;
|
messageBox.innerText = result.message;
|
||||||
messageBox.style.color = 'green';
|
messageBox.style.color = "green";
|
||||||
} else {
|
} else {
|
||||||
messageBox.innerText = result.message;
|
messageBox.innerText = result.message;
|
||||||
messageBox.style.color = 'red';
|
messageBox.style.color = "red";
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport"
|
|
||||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
||||||
<title>Document</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>LOGGED IN!!!</h1>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
169
index.js
169
index.js
@@ -1,116 +1,125 @@
|
|||||||
require('dotenv').config();
|
require("dotenv").config();
|
||||||
const express = require('express');
|
const express = require("express");
|
||||||
const session = require('express-session');
|
const session = require("express-session");
|
||||||
const port = process.env.APP_PORT;
|
const port = process.env.APP_PORT;
|
||||||
const app = express();
|
const app = express();
|
||||||
const cookieParser = require('cookie-parser');
|
const cookieParser = require("cookie-parser");
|
||||||
|
|
||||||
const path = require('path');
|
const path = require("path");
|
||||||
const { insertUser, isUserExists, changePassword, db } = require('./backend/db.js');
|
const {
|
||||||
const { initializeSocket } = require('./backend/socket.js');
|
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 saltRounds = 10;
|
||||||
const { createServer } = require('node:http');
|
const { createServer } = require("node:http");
|
||||||
const server = createServer(app);
|
const server = createServer(app);
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require("jsonwebtoken");
|
||||||
const { decode } = require("jsonwebtoken");
|
const { decode } = require("jsonwebtoken");
|
||||||
const { json } = require("express");
|
const { json } = require("express");
|
||||||
const jwtSecret = process.env.JWT_SECRET;
|
const jwtSecret = process.env.JWT_SECRET;
|
||||||
|
|
||||||
|
|
||||||
app.use(cookieParser());
|
app.use(cookieParser());
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
app.use(express.urlencoded({ extended: true }));
|
app.use(express.urlencoded({ extended: true }));
|
||||||
app.use(express.static(path.join(__dirname, 'public')));
|
app.use(express.static(path.join(__dirname, "public")));
|
||||||
app.use('/static', express.static('frontend'));
|
app.use("/static", express.static("frontend"));
|
||||||
app.use('/socket.io', express.static('node_modules/socket.io/client-dist'));
|
|
||||||
app.use(session({
|
app.use(
|
||||||
|
session({
|
||||||
secret: process.env.SESSION_SECRET,
|
secret: process.env.SESSION_SECRET,
|
||||||
resave: true,
|
resave: true,
|
||||||
saveUninitialized: true,
|
saveUninitialized: true,
|
||||||
cookie: {
|
cookie: {
|
||||||
secure: false,
|
secure: false,
|
||||||
maxAge: 30 * 24 * 60 * 60 * 1000 //30 days
|
maxAge: 30 * 24 * 60 * 60 * 1000, //30 days
|
||||||
}
|
},
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
// auth login API
|
// auth login API
|
||||||
app.post('/auth/login', async (req, res) => {
|
app.post("/auth/login", async (req, res) => {
|
||||||
await loginUser(req, res);
|
await loginUser(req, res);
|
||||||
});
|
});
|
||||||
|
|
||||||
// auth signup API
|
// auth signup API
|
||||||
app.post('/auth/signup', async (req, res) => {
|
app.post("/auth/signup", async (req, res) => {
|
||||||
await signupUser(req, res);
|
await signupUser(req, res);
|
||||||
});
|
});
|
||||||
|
|
||||||
// logout API
|
// logout API
|
||||||
app.post('/auth/logout', (req, res) => {
|
app.post("/auth/logout", (req, res) => {
|
||||||
// clear JWT token
|
// clear JWT token
|
||||||
res.clearCookie('token', {
|
res.clearCookie("token", {
|
||||||
path: '/'
|
path: "/",
|
||||||
});
|
});
|
||||||
// clear socket.io cookie (no idea what is it for but better remove it)
|
// clear socket.io cookie (no idea what is it for but better remove it)
|
||||||
res.clearCookie('io', {
|
res.clearCookie("io", {
|
||||||
path: '/'
|
path: "/",
|
||||||
});
|
});
|
||||||
res.status(200).json({ message: 'Successfully logged out' });
|
res.status(200).json({ message: "Successfully logged out" });
|
||||||
});
|
});
|
||||||
|
|
||||||
// get JWT token API
|
// get JWT token API
|
||||||
app.get('/auth/token', (req, res) => {
|
app.get("/auth/token", (req, res) => {
|
||||||
const token = req.cookies.token;
|
const token = req.cookies.token;
|
||||||
if (!token) {
|
if (!token) {
|
||||||
res.send('Not logged in');
|
res.send("Not logged in");
|
||||||
}
|
}
|
||||||
res.send(token);
|
res.send(token);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post('/auth/changePassword', async (req, res) => {
|
app.post("/auth/changePassword", async (req, res) => {
|
||||||
const token = req.cookies.token;
|
const token = req.cookies.token;
|
||||||
const { cPassword, nPassword } = req.body;
|
const { cPassword, nPassword } = req.body;
|
||||||
|
|
||||||
if (!cPassword && nPassword) {
|
if (!cPassword && nPassword) {
|
||||||
return res.json({ message: 'Field is empty' })
|
return res.json({ message: "Field is empty" });
|
||||||
}
|
}
|
||||||
if (nPassword === cPassword) {
|
if (nPassword === cPassword) {
|
||||||
return res.json({ message: 'Passwords are the same' })
|
return res.json({ message: "Passwords are the same" });
|
||||||
}
|
}
|
||||||
let username;
|
let username;
|
||||||
try {
|
try {
|
||||||
const decoded = jwt.verify(token, jwtSecret);
|
const decoded = jwt.verify(token, jwtSecret);
|
||||||
username = username = decoded.username;
|
username = decoded.username;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return res.status(403).json({ message: 'Unauthorized'});
|
return res.status(403).json({ message: "Unauthorized" });
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const result = await db.query('SELECT * FROM accounts WHERE username = $1', [username]);
|
const result = await db.query(
|
||||||
|
"SELECT * FROM accounts WHERE username = $1",
|
||||||
|
[username],
|
||||||
|
);
|
||||||
// checks that passwords are matching
|
// checks that passwords are matching
|
||||||
const match = await bcrypt.compare(cPassword, result.rows[0].password);
|
const match = await bcrypt.compare(cPassword, result.rows[0].password);
|
||||||
// if not return information
|
// if not return information
|
||||||
if (!match) {
|
if (!match) {
|
||||||
return res.status(401).json({ message: 'Current password is invalid' })
|
return res.status(401).json({ message: "Current password is invalid" });
|
||||||
}
|
}
|
||||||
// hash password
|
// hash password
|
||||||
const salt = await bcrypt.genSalt(saltRounds);
|
const salt = await bcrypt.genSalt(saltRounds);
|
||||||
const hash = await bcrypt.hash(nPassword, salt);
|
const hash = await bcrypt.hash(nPassword, salt);
|
||||||
await changePassword(username, hash);
|
await changePassword(username, hash);
|
||||||
|
|
||||||
return res.status(200).json({ message: 'Successfully changed password' });
|
return res.status(200).json({ message: "Successfully changed password" });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return res.status(500).json({ message: 'Failed to change password' });
|
return res.status(500).json({ message: "Failed to change password" });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// get username
|
// get username
|
||||||
app.get('/auth/user', (req, res) => {
|
app.get("/auth/user", (req, res) => {
|
||||||
const token = req.cookies.token;
|
const token = req.cookies.token;
|
||||||
// verify token
|
// verify token
|
||||||
if (token) {
|
if (token) {
|
||||||
jwt.verify(token, jwtSecret, (err, user) => {
|
jwt.verify(token, jwtSecret, (err, user) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return res.status(403).send('Unauthorized');
|
return res.status(403).send("Unauthorized");
|
||||||
} else {
|
} else {
|
||||||
const username = user.username;
|
const username = user.username;
|
||||||
res.json({ username });
|
res.json({ username });
|
||||||
@@ -119,12 +128,12 @@ app.get('/auth/user', (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post('/api/contacts', async(req, res) => {
|
app.post("/api/contacts", async (req, res) => {
|
||||||
const token = req.cookies.token;
|
const token = req.cookies.token;
|
||||||
if (token) {
|
if (token) {
|
||||||
jwt.verify(token, jwtSecret, (err, user) => {
|
jwt.verify(token, jwtSecret, (err, user) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return res.status(403).send('Unauthorized');
|
return res.status(403).send("Unauthorized");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -132,68 +141,66 @@ app.post('/api/contacts', async(req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// serving the login page
|
// serving the login page
|
||||||
app.get('/login', (req, res) => {
|
app.get("/login", (req, res) => {
|
||||||
const token = req.cookies.token;
|
const token = req.cookies.token;
|
||||||
// verify token
|
// verify token
|
||||||
if (token) {
|
if (token) {
|
||||||
res.json({ Error: 'Already logged in' });
|
res.json({ Error: "Already logged in" });
|
||||||
} else {
|
} else {
|
||||||
res.sendFile(path.join(__dirname, '/frontend/routes/login.html'));
|
res.sendFile(path.join(__dirname, "/frontend/routes/login.html"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// serving the signup page
|
// serving the signup page
|
||||||
app.get('/signup', (req, res) => {
|
app.get("/signup", (req, res) => {
|
||||||
const token = req.cookies.token;
|
const token = req.cookies.token;
|
||||||
if (token) {
|
if (token) {
|
||||||
res.json({ Error: 'Already logged in' });
|
res.json({ Error: "Already logged in" });
|
||||||
} else
|
} else res.sendFile(path.join(__dirname, "/frontend/routes/signup.html"));
|
||||||
res.sendFile(path.join(__dirname, '/frontend/routes/signup.html'));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/settings', (req, res) => {
|
app.get("/settings", (req, res) => {
|
||||||
const token = req.cookies.token;
|
const token = req.cookies.token;
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
res.redirect('/login');
|
res.redirect("/login");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// verify token
|
// verify token
|
||||||
jwt.verify(token, jwtSecret, (err) => {
|
jwt.verify(token, jwtSecret, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return res.status(403).send('Unauthorized');
|
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) => {
|
app.get("/", (req, res) => {
|
||||||
const token = req.cookies.token;
|
const token = req.cookies.token;
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return res.redirect('/login');
|
return res.redirect("/login");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return res.redirect('/chat');
|
return res.redirect("/chat");
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
// serving the chat page if logged in
|
// serving the chat page if logged in
|
||||||
app.get('/chat', (req, res) => {
|
app.get("/chat", (req, res) => {
|
||||||
const token = req.cookies.token;
|
const token = req.cookies.token;
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
res.redirect('/login');
|
res.redirect("/login");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// verify token
|
// verify token
|
||||||
jwt.verify(token, jwtSecret, (err) => {
|
jwt.verify(token, jwtSecret, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return res.status(403).send('Unauthorized');
|
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
|
// run server
|
||||||
server.listen(port, () => {
|
server.listen(port, () => {
|
||||||
@@ -210,8 +217,8 @@ async function signupUser(req, res) {
|
|||||||
// Check if user exists
|
// Check if user exists
|
||||||
const exists = await isUserExists(username);
|
const exists = await isUserExists(username);
|
||||||
if (exists) {
|
if (exists) {
|
||||||
console.log('User already exists');
|
console.log("User already exists");
|
||||||
return res.status(500).json({ message: 'User already exists!' });
|
return res.status(500).json({ message: "User already exists!" });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hash password
|
// Hash password
|
||||||
@@ -222,17 +229,16 @@ async function signupUser(req, res) {
|
|||||||
await insertUser(username, hash);
|
await insertUser(username, hash);
|
||||||
return res.status(200).json({ message: "Account successfully created" });
|
return res.status(200).json({ message: "Account successfully created" });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error inserting data:', err);
|
console.error("Error inserting data:", err);
|
||||||
return res.status(500).json({ message: 'Error inserting data' });
|
return res.status(500).json({ message: "Error inserting data" });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
res.status(400).json({ message: 'Form is empty'})
|
res.status(400).json({ message: "Form is empty" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// login function
|
// login function
|
||||||
async function loginUser(req, res) {
|
async function loginUser(req, res) {
|
||||||
|
|
||||||
let username = req.body.username;
|
let username = req.body.username;
|
||||||
let password = req.body.password;
|
let password = req.body.password;
|
||||||
|
|
||||||
@@ -241,34 +247,39 @@ async function loginUser(req, res) {
|
|||||||
username = username.trim();
|
username = username.trim();
|
||||||
password = password.trim();
|
password = password.trim();
|
||||||
|
|
||||||
const result = await db.query('SELECT * FROM accounts WHERE username = $1', [username]);
|
const result = await db.query(
|
||||||
|
"SELECT * FROM accounts WHERE username = $1",
|
||||||
|
[username],
|
||||||
|
);
|
||||||
// check if user exists
|
// check if user exists
|
||||||
if (result.rows.length > 0) {
|
if (result.rows.length > 0) {
|
||||||
// Compare password
|
// Compare password
|
||||||
const match = await bcrypt.compare(password, result.rows[0].password);
|
const match = await bcrypt.compare(password, result.rows[0].password);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
res.status(401).json({ message: 'Invalid password'});
|
res.status(401).json({ message: "Invalid password" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const token = jwt.sign({ username }, jwtSecret, {
|
const token = jwt.sign({ username }, jwtSecret, {
|
||||||
expiresIn: '30d' // token expires in 30 days
|
expiresIn: "30d", // token expires in 30 days
|
||||||
});
|
});
|
||||||
res.cookie('token', token, {
|
res.cookie("token", token, {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
maxAge: 30 * 24 * 60 * 60 * 1000 // 30 days
|
maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days
|
||||||
});
|
});
|
||||||
req.session.loggedin = true;
|
req.session.loggedin = true;
|
||||||
req.session.username = username;
|
req.session.username = username;
|
||||||
res.status(200).json({ message: 'Successfully logged in' });
|
res.status(200).json({ message: "Successfully logged in" });
|
||||||
} else {
|
} else {
|
||||||
return res.status(401).json({ message: 'Incorrect Username or Password!'})
|
return res
|
||||||
|
.status(401)
|
||||||
|
.json({ message: "Incorrect Username or Password!" });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error executing query', error);
|
console.error("Error executing query", error);
|
||||||
res.status(500).json({ message: 'Internal server error' });
|
res.status(500).json({ message: "Internal server error" });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
res.status(400).json({ message: 'Please enter Username and Password!' });
|
res.status(400).json({ message: "Please enter Username and Password!" });
|
||||||
}
|
}
|
||||||
res.end();
|
res.end();
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user