added contact db

This commit is contained in:
slawk0
2024-10-12 00:45:53 +02:00
parent bd89f0762f
commit 8414919ae6
7 changed files with 220 additions and 91 deletions

View File

@@ -10,12 +10,14 @@
"dependencies": {
"@tailwindcss/forms": "^0.5.9",
"@types/js-cookie": "^3.0.6",
"@types/socket.io-client": "^1.4.36",
"axios": "^1.7.7",
"js-cookie": "^3.0.5",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.53.0",
"react-router-dom": "^6.26.2"
"react-router-dom": "^6.26.2",
"socket.io-client": "^4.8.0"
},
"devDependencies": {
"@eslint/js": "^9.9.0",
@@ -1296,6 +1298,12 @@
"win32"
]
},
"node_modules/@socket.io/component-emitter": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
"license": "MIT"
},
"node_modules/@tailwindcss/forms": {
"version": "0.5.9",
"resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.9.tgz",
@@ -1401,6 +1409,12 @@
"@types/react": "*"
}
},
"node_modules/@types/socket.io-client": {
"version": "1.4.36",
"resolved": "https://registry.npmjs.org/@types/socket.io-client/-/socket.io-client-1.4.36.tgz",
"integrity": "sha512-ZJWjtFBeBy1kRSYpVbeGYTElf6BqPQUkXDlHHD4k/42byCN5Rh027f4yARHCink9sKAkbtGZXEAmR0ZCnc2/Ag==",
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.7.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.7.0.tgz",
@@ -2066,7 +2080,6 @@
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -2127,6 +2140,28 @@
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"license": "MIT"
},
"node_modules/engine.io-client": {
"version": "6.6.1",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.1.tgz",
"integrity": "sha512-aYuoak7I+R83M/BBPIOs2to51BmFIpC1wZe6zZzMrT2llVsHy5cvcmdsJgP2Qz6smHu+sD9oexiSUAVd8OfBPw==",
"license": "MIT",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1",
"engine.io-parser": "~5.2.1",
"ws": "~8.17.1",
"xmlhttprequest-ssl": "~2.1.1"
}
},
"node_modules/engine.io-parser": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
"integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/esbuild": {
"version": "0.21.5",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
@@ -3151,7 +3186,6 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"license": "MIT"
},
"node_modules/mz": {
@@ -3862,6 +3896,34 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/socket.io-client": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.0.tgz",
"integrity": "sha512-C0jdhD5yQahMws9alf/yvtsMGTaIDBnZ8Rb5HU56svyq0l5LIrGzIDZZD5pHQlmzxLuU91Gz+VpQMKgCTNYtkw==",
"license": "MIT",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.2",
"engine.io-client": "~6.6.1",
"socket.io-parser": "~4.2.4"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/socket.io-parser": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
"license": "MIT",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -4437,6 +4499,35 @@
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/ws": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/xmlhttprequest-ssl": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.1.tgz",
"integrity": "sha512-ptjR8YSJIXoA3Mbv5po7RtSYHO6mZr8s7i5VGmEk7QY2pQWyT1o0N+W1gKbOyJPUCGXGnuw0wqe8f0L6Y0ny7g==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",

View File

@@ -12,12 +12,14 @@
"dependencies": {
"@tailwindcss/forms": "^0.5.9",
"@types/js-cookie": "^3.0.6",
"@types/socket.io-client": "^1.4.36",
"axios": "^1.7.7",
"js-cookie": "^3.0.5",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.53.0",
"react-router-dom": "^6.26.2"
"react-router-dom": "^6.26.2",
"socket.io-client": "^4.8.0"
},
"devDependencies": {
"@eslint/js": "^9.9.0",

View File

@@ -1,43 +1,6 @@
import { useForm, SubmitHandler } from "react-hook-form";
import zdjecie from "../../assets/walter.png";
const messagesArray = [
{
content: "widomosc jakas",
username: "wyslal wiadomosc",
recipient: "jakis odbiorca",
},
{
content: "widomosc jakas",
username: "wyslal wiadomosc",
recipient: "jakis odbiorca",
},
{
content: "widomosc jakas",
username: "wyslal wiadomosc",
recipient: "jakis odbiorca",
},
{
content: "widomosc jakas",
username: "wyslal wiadomosc",
recipient: "jakis odbiorca",
},
{
content: "widomosc jakas",
username: "wyslal wiadomosc",
recipient: "jakis odbiorca",
},
{
content: "widomosc jakas",
username: "wyslal wiadomosc",
recipient: "jakis odbiorca",
},
{
content: "widomosc jakas",
username: "wyslal wiadomosc",
recipient: "jakis odbiorca",
},
];
import { sendMessage } from "../socket/socket.tsx";
type Input = {
message: string;
contact: string;
@@ -53,8 +16,13 @@ function Chat() {
// Sending message
const submitMessage: SubmitHandler<Input> = (data) => {
console.log("wiadomoscs: " + data.message + "zostala wyslana");
if (!data.message) {
return;
}
console.log("message: " + data.message + " was sent");
sendMessage(data.message);
reset();
console.log("form reset");
};
// Sending contact
@@ -94,35 +62,6 @@ function Chat() {
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
<li>jdjskskbkskskaoso</li>
</ul>
</div>
{/*Profile element*/}
@@ -145,11 +84,11 @@ function Chat() {
<div>
<p>wiadomosci</p>
<ul className="ml-5">
{messagesArray.map((message, index) => (
<li key={index}>
{message.username}: {message.content}
</li>
))}
{/*{messagesArray.map((message, index) => (*/}
{/* <li key={index}>*/}
{/* {message.username}: {message.content}*/}
{/* </li>*/}
{/*))}*/}
</ul>
</div>
{/*Messages input*/}
@@ -168,7 +107,6 @@ function Chat() {
{errors?.message?.type === "maxLength" && (
<p>Maximum length of the message is 500</p>
)}
<button
className="text-black bg-green-500 hover:bg-green-400 font-bold py-2 px-4 rounded mr-1 w-24 "
type="submit"

View File

@@ -0,0 +1,18 @@
import { io } from "socket.io-client";
import Cookie from "js-cookie";
const socket = io({
auth: {
token: Cookie.get("token"),
},
});
socket.on("connect", () => console.log("connected"));
socket.on("disconnect", () => {
console.log("Disconnected from server");
});
function sendMessage(message: string) {
socket.emit("chat message", message);
}
export { sendMessage };

View File

@@ -53,6 +53,16 @@ async function createTables() {
} catch (e) {
console.error("Failed to create messages table ", e);
}
try {
await client.query(`
CREATE TABLE IF NOT EXISTS contacts (
username VARCHAR(20),
usernameContact VARCHAR(20),
);
`);
} catch (e) {
console.error("Failed to create messages table ", e);
}
}
async function insertUser(username, password, user_id, created_at) {
@@ -61,7 +71,7 @@ async function insertUser(username, password, user_id, created_at) {
VALUES ($1, $2, $3, $4);
`;
try {
client.query(query, [username, password, user_id, created_at]);
await client.query(query, [username, password, user_id, created_at]);
} catch (e) {
console.error("Failed to insert user ", e);
}
@@ -74,7 +84,7 @@ async function insertMessage(sender_id, receiver_id, message) {
RETURNING id;
`;
try {
client.query(query, [sender_id, receiver_id, message]);
await client.query(query, [sender_id, receiver_id, message]);
} catch (e) {
console.error("Failed to insert message ", e);
}
@@ -114,11 +124,35 @@ async function changePassword(username, newPassword) {
WHERE username = $2;
`;
try {
client.query(query, [newPassword, username]);
await client.query(query, [newPassword, username]);
} catch (e) {
console.error("Failed to change password ", e);
}
}
async function insertContact(username, usernameContact) {
const query = `
INSERT INTO contacts (username, usernameContact)
VALUES ($1, $2) ;
`;
try {
await client.query(query, [username, usernameContact]);
} catch (e) {
console.error("Failed to insert contact ", e);
}
}
async function removeContact(username, usernameContact) {
const query = `
DELETE FROM contacts
WHERE (username = $1 AND contact = $2);
`;
try {
await client.query(query, [username, usernameContact]);
} catch (e) {
console.error("Failed to remove contact ", e);
}
}
module.exports = {
client,
insertUser,
@@ -126,4 +160,6 @@ module.exports = {
checkUserExist,
changePassword,
getPassword,
insertContact,
removeContact,
};

View File

@@ -1,10 +1,8 @@
const express = require("express");
const { createServer } = require("http");
const { Server } = require("socket.io");
const app = express();
const cors = require("cors");
const server = createServer(app);
const io = new Server(server);
const bodyParser = require("body-parser");
const cookieParser = require("cookie-parser");
const bcrypt = require("bcrypt");
@@ -20,9 +18,10 @@ const {
insertMessage,
checkUserExist,
changePassword,
getPassword,
} = require("./db/db.js");
const { generateJwtToken, verifyJwtToken } = require("./auth/jwt");
const { getPassword } = require("./db/db");
const { initializeSocket } = require("./socket/socket");
const corsOptions = {
origin: process.env.ORIGIN,
@@ -42,12 +41,14 @@ app.post("/api/auth/signup", async (req, res) => {
const user_id = crypto.randomUUID();
const created_at = new Date();
// Validate form data length
if (!username || username.length < 4 || username.length > 20) {
return res.status(400).json({ message: "Invalid username length" });
}
if (!password || password.length < 8 || password.length > 128) {
return res.status(400).json({ message: "Invalid password length" });
}
// Checks if the user already exists in database (returns result.rows[0].count > 0;)
const exist = await checkUserExist(username);
if (exist) {
@@ -77,17 +78,30 @@ app.post("/api/auth/login", async (req, res) => {
const username = req.body.username;
const password = req.body.password;
if (
!username ||
!password ||
username.length < 4 ||
username.length > 20 ||
password.length < 8 ||
password.length > 128
) {
return res.status(400).json({ message: "Invalid credentials" });
}
// Checks if the user exist
const exist = await checkUserExist(username);
if (!exist) {
res.status(404).json({ message: "User does not exist" });
return;
return res.status(404).json({ message: "User does not exist" });
}
// Compare passwords
const hashedPassword = await getPassword(username);
bcrypt.compare(password, hashedPassword, (err, result) => {
if (err) {
console.error("Failed to compare password ", err);
return result;
}
// If compare was successfully generate JWT token and store in cookies
if (result) {
const token = generateJwtToken(username); //TODO add username_id
res.cookie("token", token, {
@@ -99,7 +113,7 @@ app.post("/api/auth/login", async (req, res) => {
}
});
});
let count = 0;
app.get("/api/auth/validate", (req, res) => {
const token = req.cookies.token;
if (!token) {
@@ -107,16 +121,14 @@ app.get("/api/auth/validate", (req, res) => {
}
const { username } = verifyJwtToken(token);
if (username) {
console.log(count++);
return res
.status(200)
.json({ message: "Authorized", username: username.username });
}
res.status(401).json({ message: "Unauthorized" });
});
io.on("connection", (socket) => {
console.log(`User: ${socket.id} just connected`);
});
initializeSocket(server);
server.listen(PORT, () => {
console.log(`Server is running on port: ${PORT}`);

View File

@@ -0,0 +1,32 @@
const { Server } = require("socket.io");
const { insertMessage } = require("../db/db");
const { verifyJwtToken } = require("../auth/jwt");
function initializeSocket(server) {
const io = new Server(server);
io.use((socket, next) => {
const token = socket.handshake.auth;
if (!token) {
socket.disconnect();
}
const { username } = verifyJwtToken(token);
if (!username) {
socket.disconnect();
}
});
io.on("connection", (socket) => {
console.log("connected");
socket.on("chat message", (msg) => {
insertMessage(msg);
console.log("message", msg);
});
socket.on("disconnect", () => {
console.log("User disconnected");
});
});
}
module.exports = { initializeSocket };