// Express is used for HTTP and URL routing const express = require('express'); const path = require('path'); const PORT = process.env.PORT || 5000; // Library to generate unique identifiers const { v4: uuidv4 } = require('uuid'); const uuid = require('uuid'); // We need the crypto library for sha512 encryption of passwords in the database var crypto = require("crypto"); // psql driver const { Pool } = require('pg'); const app = express(); const http = require('http'); const server = http.createServer(app); const io = require('socket.io')(server, { cors: { origin: "*" } }); /* Connects to database on deployed app. */ const pool = new Pool({ connectionString: process.env.DATABASE_URL, ssl: { rejectUnauthorized: false } }); app.use(express.json()) app.use(express.urlencoded({ extended: true })) users = {} io.on("connection", (socket) => { socket.emit("hello", {"hello": "world"}); socket.on('disconnect', () => { console.log('user disconnected'); delete users[socket.id]; socket.broadcast.emit('users', getUsers()); }); socket.on("hello", (arg) => { console.log("hello" + arg); // world }); socket.on("message", (arg) => { socket.broadcast.emit('message', arg); saveMessage(users[socket.id], arg); }); socket.on("privateMessage", (msg, to) => { var socketID = []; for (user in users){ console.log(user); if (users[user].toString() == to.toString()){ } } console.log("Private message to " + to + " " + socketID[0]); io.to(socketID[0]).emit('privateMessage', users[socket.id], msg); saveMessage(users[socket.id], users[socketID[0]], msg); }); socket.on("login", (data) => { data = data.split(","); var username = data[0]; var pw = data[1]; pool.query(`SELECT username,password FROM accounts where username='${username}'`, (err, result) => { if (err){ error('A critical database error occured while user was attempting to login'); socket.emit('logInError', 'A critical database error occured while user was attempting to login'); } else if (result.rowCount == 0){ socket.emit('logInError', `Invalid credentials`); } else if (result.rows[0].username == username && result.rows[0].password == sha512(pw)){ var uhash = sha512(username); socket.emit('users', getUsers()); users[socket.id] = username; socket.broadcast.emit('users', getUsers()); socket.emit('loggedIn', `${username}`); getMessages(); log('User logged in'); } else { socket.emit('logInError', `Invalid credentials`); } }); }); socket.on("register", (data) => { data = data.split(","); var id = uuidv4(); var username = data[0]; var pw = data[1]; pool.query(`SELECT * FROM accounts where username='${username}'`, (err, result) => { if (err) { error(err); error('A critical database error occured while user was attempting to create an account'); socket.emit('registerError', 'A critical database error occured while user was attempting to create an account'); } else { if (result.rowCount == 0){ var pwhash = sha512(pw); var uhash = sha512(username); pool.query(`insert into accounts values('${id}', '${username}', '${pwhash}')`, (err, result) => { console.log(err); console.log(result); if (err){ socket.emit('registerError', 'A critical database error occured while user was attempting to create an account'); } else { socket.username = username; socket.emit('registered', `${username}`); log(`${username} registered with ${id}`); } }); } else { socket.emit('registerError', `Username already exists`); } } }) }); function getMessages(){ pool.query(`SELECT MESSAGE FROM message where TO_USER='all'`, (err, result) => { //console.log(result.rows); console.log("GETTING MESSAGES"); socket.emit('messages', result.rows); }); } }); /** * hash password with sha512. * @function * @param {string} password - List of required fields. * @param {string} salt - Data to be validated. */ var sha512 = function(password, salt = "messaging"){ var hash = crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */ hash.update(password); var value = hash.digest('hex'); return value; }; server.listen(PORT, function(){ log("Listening on port " + PORT); }) function getUsers(){ u = []; for (user in users){ u.push(users[user]); } return u; } function saveMessage(from, msg){ pool.query(`insert into message values('${from}', 'all', '${msg}')`, (err, result) => {}); } function savePrivateMessage(from, to, msg){ pool.query(`insert into message values('${from}', '${to}', '${msg}')`, (err, result) => {}); } function log(input){ console.log(input); } function error(input){ console.error(input); }