From 4cb297ad44ca258f56dff19214239df34e3c79e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20BRAVO?= <96313051+loicBRAVO@users.noreply.github.com> Date: Mon, 29 Jan 2024 16:50:35 +0100 Subject: [PATCH 1/4] Add mongoose and socket.io dependencies, connect to MongoDB, and implement socket.io functionality --- back/dist/index.js | 50 +++- back/dist/models/Message.js | 11 + back/package-lock.json | 429 ++++++++++++++++++++++++++++++++++- back/package.json | 4 +- back/src/index.ts | 54 ++++- back/src/models/Message.d.ts | 10 + back/src/models/Message.ts | 12 + front/public/index.html | 42 ++++ 8 files changed, 593 insertions(+), 19 deletions(-) create mode 100644 back/dist/models/Message.js create mode 100644 back/src/models/Message.d.ts create mode 100644 back/src/models/Message.ts create mode 100644 front/public/index.html diff --git a/back/dist/index.js b/back/dist/index.js index 889d2d8..cafc4f4 100644 --- a/back/dist/index.js +++ b/back/dist/index.js @@ -1,16 +1,56 @@ "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const express_1 = __importDefault(require("express")); +const http_1 = __importDefault(require("http")); +const socket_io_1 = require("socket.io"); +const mongoose = require('mongoose'); +const Message_1 = __importDefault(require("./models/Message")); const dotenv_1 = __importDefault(require("dotenv")); dotenv_1.default.config(); +// Connect to MongoDB +mongoose.connect(`mongodb://${process.env.MONGO_INITDB_ROOT_USERNAME}:${process.env.MONGO_INITDB_ROOT_PASSWORD}@localhost:27017/${process.env.MONGO_INITDB_DATABASE}`) + .then(() => console.log('Connected to MongoDB')) + .catch((err) => console.error('Could not connect to MongoDB', err)); const app = (0, express_1.default)(); -const port = process.env.PORT || 3000; -app.get("/", (req, res) => { - res.send("Express + TypeScript Server"); +const server = http_1.default.createServer(app); +const io = new socket_io_1.Server(server); +const PORT = 3000; +// Start the server +server.listen(PORT, () => { + console.log(`Server running on port ${PORT}`); }); -app.listen(port, () => { - console.log(`[server]: Server is running at http://localhost:${port}`); +io.on('connection', (socket) => { + console.log('User connected:', socket.id); + // Listen for incoming chat messages + socket.on('chat message', (data) => __awaiter(void 0, void 0, void 0, function* () { + console.log('Received message:', data); + // Save the message to MongoDB + const message = new Message_1.default({ user: data.user, text: data.message }); + try { + yield message.save(); + console.log('Message saved to the database'); + // Broadcast the message to all connected clients + io.emit('chat message', data); + } + catch (err) { + console.error('Error saving message to database:', err); + } + })); + // Listen for user disconnection + socket.on('disconnect', () => { + console.log('User disconnected:', socket.id); + }); }); +app.use(express_1.default.static('../front/public/')); diff --git a/back/dist/models/Message.js b/back/dist/models/Message.js new file mode 100644 index 0000000..432b2bd --- /dev/null +++ b/back/dist/models/Message.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +// Message.js becomes Message.ts +const mongoose = require('mongoose'); +const messageSchema = new mongoose.Schema({ + user: String, + text: String, + timestamp: { type: Date, default: Date.now }, +}); +const Message = mongoose.model('Message', messageSchema); +exports.default = Message; diff --git a/back/package-lock.json b/back/package-lock.json index 9e3b0f5..38f0c97 100644 --- a/back/package-lock.json +++ b/back/package-lock.json @@ -10,7 +10,9 @@ "license": "ISC", "dependencies": { "dotenv": "^16.3.2", - "express": "^4.18.2" + "express": "^4.18.2", + "mongoose": "^8.1.1", + "socket.io": "^4.7.4" }, "devDependencies": { "@types/express": "^4.17.21", @@ -70,6 +72,19 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.4.tgz", + "integrity": "sha512-8zJ8N1x51xo9hwPh6AWnKdLGEC5N3lDa6kms1YHmFBoRhTpJR6HG8wWk0td1MVCu9cD4YBrvjZEtd5Obw0Fbnw==", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -113,6 +128,19 @@ "@types/node": "*" } }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/express": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", @@ -153,7 +181,6 @@ "version": "20.11.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.5.tgz", "integrity": "sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==", - "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -191,6 +218,19 @@ "@types/node": "*" } }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" + }, + "node_modules/@types/whatwg-url": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.4.tgz", + "integrity": "sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==", + "dependencies": { + "@types/webidl-conversions": "*" + } + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -284,6 +324,14 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -338,6 +386,14 @@ "node": ">=8" } }, + "node_modules/bson": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.2.0.tgz", + "integrity": "sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==", + "engines": { + "node": ">=16.20.1" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -544,6 +600,18 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -643,6 +711,63 @@ "node": ">= 0.8" } }, + "node_modules/engine.io": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz", + "integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==", + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz", + "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/engine.io/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -968,6 +1093,14 @@ "node": ">=0.12.0" } }, + "node_modules/kareem": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", + "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -1000,6 +1133,11 @@ "node": ">= 0.6" } }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -1055,6 +1193,126 @@ "node": "*" } }, + "node_modules/mongodb": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz", + "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==", + "dependencies": { + "@mongodb-js/saslprep": "^1.1.0", + "bson": "^6.2.0", + "mongodb-connection-string-url": "^3.0.0" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz", + "integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==", + "dependencies": { + "@types/whatwg-url": "^11.0.2", + "whatwg-url": "^13.0.0" + } + }, + "node_modules/mongoose": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.1.1.tgz", + "integrity": "sha512-DbLb0NsiEXmaqLOpEz+AtAsgwhRw6f25gwa1dF5R7jj6lS1D8X6uTdhBSC8GDVtOwe5Tfw2EL7nTn6hiJT3Bgg==", + "dependencies": { + "bson": "^6.2.0", + "kareem": "2.5.1", + "mongodb": "6.3.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "16.0.1" + }, + "engines": { + "node": ">=16.20.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mongoose/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/mquery/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mquery/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -1143,6 +1401,14 @@ "node": ">=0.10.0" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -1205,6 +1471,14 @@ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -1400,6 +1674,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sift": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", + "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" + }, "node_modules/simple-update-notifier": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", @@ -1412,6 +1691,93 @@ "node": ">=10" } }, + "node_modules/socket.io": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.4.tgz", + "integrity": "sha512-DcotgfP1Zg9iP/dH9zvAQcWrE0TtbMVwXmlV4T4mqsvY+gw+LqUGPfx2AoVyRk0FLME+GQhufDMyacFmw7ksqw==", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.5.2", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "dependencies": { + "ws": "~8.11.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==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io-parser/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/socket.io/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "dependencies": { + "memory-pager": "^1.0.2" + } + }, "node_modules/spawn-command": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", @@ -1496,6 +1862,17 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -1588,8 +1965,7 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "node_modules/unpipe": { "version": "1.0.0", @@ -1621,6 +1997,26 @@ "node": ">= 0.8" } }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", + "dependencies": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -1638,6 +2034,26 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "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/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -1688,6 +2104,11 @@ "engines": { "node": ">=6" } + }, + "socket_test": { + "name": "socket-test", + "version": "0.0.1", + "extraneous": true } } } diff --git a/back/package.json b/back/package.json index e43357d..9926175 100644 --- a/back/package.json +++ b/back/package.json @@ -11,7 +11,9 @@ "license": "ISC", "dependencies": { "dotenv": "^16.3.2", - "express": "^4.18.2" + "express": "^4.18.2", + "mongoose": "^8.1.1", + "socket.io": "^4.7.4" }, "devDependencies": { "@types/express": "^4.17.21", diff --git a/back/src/index.ts b/back/src/index.ts index 03bc3e2..28931d7 100644 --- a/back/src/index.ts +++ b/back/src/index.ts @@ -1,15 +1,51 @@ -import express, { Express, Request, Response } from "express"; -import dotenv from "dotenv"; - +import express from 'express'; +import http from 'http'; +import { Server as SocketIOServer } from 'socket.io'; +const mongoose = require('mongoose'); +import Message from './models/Message'; +import dotenv from 'dotenv'; dotenv.config(); -const app: Express = express(); -const port = process.env.PORT || 3000; -app.get("/", (req: Request, res: Response) => { - res.send("Express + TypeScript Server"); +// Connect to MongoDB +mongoose.connect(`mongodb://${process.env.MONGO_INITDB_ROOT_USERNAME}:${process.env.MONGO_INITDB_ROOT_PASSWORD}@localhost:27017/${process.env.MONGO_INITDB_DATABASE}`) + .then(() => console.log('Connected to MongoDB')) + .catch((err:any) => console.error('Could not connect to MongoDB', err)); + +const app = express(); +const server = http.createServer(app); +const io = new SocketIOServer(server); + +const PORT = 3000; + +// Start the server +server.listen(PORT, () => { + console.log(`Server running on port ${PORT}`); }); -app.listen(port, () => { - console.log(`[server]: Server is running at http://localhost:${port}`); +io.on('connection', (socket) => { + console.log('User connected:', socket.id); + + // Listen for incoming chat messages + socket.on('chat message', async (data) => { + console.log('Received message:', data); + + // Save the message to MongoDB + const message = new Message({ user: data.user, text: data.message }); + try { + await message.save(); + console.log('Message saved to the database'); + // Broadcast the message to all connected clients + io.emit('chat message', data); + } catch (err) { + console.error('Error saving message to database:', err); + } + }); + + // Listen for user disconnection + socket.on('disconnect', () => { + console.log('User disconnected:', socket.id); + }); }); + +app.use(express.static('../front/public/')); diff --git a/back/src/models/Message.d.ts b/back/src/models/Message.d.ts new file mode 100644 index 0000000..29b70e1 --- /dev/null +++ b/back/src/models/Message.d.ts @@ -0,0 +1,10 @@ +// Message.d.ts +import { Document, Model } from 'mongoose'; + +export interface IMessage extends Document { + user: string; + text: string; + timestamp: Date; +} + +export const Message: Model; diff --git a/back/src/models/Message.ts b/back/src/models/Message.ts new file mode 100644 index 0000000..1544f23 --- /dev/null +++ b/back/src/models/Message.ts @@ -0,0 +1,12 @@ +// Message.js becomes Message.ts +const mongoose = require('mongoose'); + +const messageSchema = new mongoose.Schema({ + user: String, + text: String, + timestamp: { type: Date, default: Date.now }, +}); + +const Message = mongoose.model('Message', messageSchema); + +export default Message; diff --git a/front/public/index.html b/front/public/index.html new file mode 100644 index 0000000..626e72a --- /dev/null +++ b/front/public/index.html @@ -0,0 +1,42 @@ + + + + + + Real-Time Chat + + +

Real-Time Chat App

+
+ +
+ + +
+
+ + + + + \ No newline at end of file From 350a420c85f4cfd6f6044eececdaeeb8ce9577e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20BRAVO?= <96313051+loicBRAVO@users.noreply.github.com> Date: Tue, 30 Jan 2024 11:03:41 +0100 Subject: [PATCH 2/4] Refactor message schema and update MongoDB connection string --- back/init-mongo.js | 8 ++++---- back/src/index.ts | 24 +++++++++++++++++------- back/src/models/Message.d.ts | 10 ---------- back/src/models/Message.ts | 28 ++++++++++++++++++++-------- front/public/index.html | 6 ++++++ 5 files changed, 47 insertions(+), 29 deletions(-) delete mode 100644 back/src/models/Message.d.ts diff --git a/back/init-mongo.js b/back/init-mongo.js index f46e2f1..0b89b30 100644 --- a/back/init-mongo.js +++ b/back/init-mongo.js @@ -8,11 +8,11 @@ db.createCollection("messages", { validator: { $jsonSchema: { bsonType: "object", - required: ["conversationId", "messages"], + required: ["messages"], properties: { - conversationId: { - bsonType: "objectId", - }, + // conversationId: { + // bsonType: "objectId", + // }, messages: { bsonType: "array", items: { diff --git a/back/src/index.ts b/back/src/index.ts index dde225f..a8e1db5 100644 --- a/back/src/index.ts +++ b/back/src/index.ts @@ -1,16 +1,15 @@ import express from 'express'; import http from 'http'; import { Server as SocketIOServer } from 'socket.io'; -const mongoose = require('mongoose'); +import mongoose from 'mongoose'; import Message from './models/Message'; import dotenv from 'dotenv'; dotenv.config(); - // Connect to MongoDB -mongoose.connect(`mongodb://${process.env.MONGO_INITDB_ROOT_USERNAME}:${process.env.MONGO_INITDB_ROOT_PASSWORD}@localhost:27017/${process.env.MONGO_INITDB_DATABASE}`) +mongoose.connect(`mongodb://${process.env.MONGODB_USER}:${process.env.MONGODB_USER_PASSWORD}@localhost:27017/${process.env.MONGO_INITDB_DATABASE}`) .then(() => console.log('Connected to MongoDB')) - .catch((err:any) => console.error('Could not connect to MongoDB', err)); + .catch((err: any) => console.error('Could not connect to MongoDB', err)); const app = express(); const server = http.createServer(app); @@ -30,11 +29,22 @@ io.on('connection', (socket) => { socket.on('chat message', async (data) => { console.log('Received message:', data); - // Save the message to MongoDB - const message = new Message({ user: data.user, text: data.message }); + // Prepare the message document according to the updated schema + const messageDocument = { + messages: [{ + timestamp: new Date(), + content: data.message, + }] + }; + + // Instantiate the Message model with the document + const messageModel = new Message(messageDocument); + try { - await message.save(); + // Save the message document to MongoDB + await messageModel.save(); console.log('Message saved to the database'); + // Broadcast the message to all connected clients io.emit('chat message', data); } catch (err) { diff --git a/back/src/models/Message.d.ts b/back/src/models/Message.d.ts deleted file mode 100644 index 29b70e1..0000000 --- a/back/src/models/Message.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -// Message.d.ts -import { Document, Model } from 'mongoose'; - -export interface IMessage extends Document { - user: string; - text: string; - timestamp: Date; -} - -export const Message: Model; diff --git a/back/src/models/Message.ts b/back/src/models/Message.ts index 1544f23..f7923f5 100644 --- a/back/src/models/Message.ts +++ b/back/src/models/Message.ts @@ -1,12 +1,24 @@ -// Message.js becomes Message.ts -const mongoose = require('mongoose'); +import mongoose, { Schema, Document, Model } from 'mongoose'; -const messageSchema = new mongoose.Schema({ - user: String, - text: String, - timestamp: { type: Date, default: Date.now }, +interface IMessageItem { + timestamp: Date; + content: string; +} + +// Interface for the document structure +interface IMessageDocument extends Document { + messages: IMessageItem[]; +} + +const messageItemSchema = new Schema({ + timestamp: { type: Date, required: true }, + content: { type: String, required: true } +}); + +const messageSchema = new Schema({ + messages: [messageItemSchema] }); -const Message = mongoose.model('Message', messageSchema); +const MessageModel: Model = mongoose.model('Message', messageSchema); -export default Message; +export default MessageModel; diff --git a/front/public/index.html b/front/public/index.html index 626e72a..7e1c13f 100644 --- a/front/public/index.html +++ b/front/public/index.html @@ -38,5 +38,11 @@

Real-Time Chat App

} }); + \ No newline at end of file From aaf9049524b12d1b339eda67e05412db662576c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20BRAVO?= <96313051+loicBRAVO@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:16:19 +0100 Subject: [PATCH 3/4] Fix message saving and add static file serving --- back/dist/index.js | 2 +- back/dist/models/Message.js | 10 +++++----- back/src/index.ts | 10 +++++++++- back/src/models/Users.ts | 18 ++++++++++++++++++ 4 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 back/src/models/Users.ts diff --git a/back/dist/index.js b/back/dist/index.js index cafc4f4..fc3b801 100644 --- a/back/dist/index.js +++ b/back/dist/index.js @@ -41,13 +41,13 @@ io.on('connection', (socket) => { try { yield message.save(); console.log('Message saved to the database'); - // Broadcast the message to all connected clients io.emit('chat message', data); } catch (err) { console.error('Error saving message to database:', err); } })); + // Listen for user disconnection socket.on('disconnect', () => { console.log('User disconnected:', socket.id); diff --git a/back/dist/models/Message.js b/back/dist/models/Message.js index 432b2bd..234d372 100644 --- a/back/dist/models/Message.js +++ b/back/dist/models/Message.js @@ -1,11 +1,11 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // Message.js becomes Message.ts -const mongoose = require('mongoose'); +const mongoose = require("mongoose"); const messageSchema = new mongoose.Schema({ - user: String, - text: String, - timestamp: { type: Date, default: Date.now }, + user: String, + text: String, + timestamp: { type: Date, default: Date.now }, }); -const Message = mongoose.model('Message', messageSchema); +const Message = mongoose.model("Message", messageSchema); exports.default = Message; diff --git a/back/src/index.ts b/back/src/index.ts index a8e1db5..a7bd2be 100644 --- a/back/src/index.ts +++ b/back/src/index.ts @@ -4,8 +4,12 @@ import { Server as SocketIOServer } from 'socket.io'; import mongoose from 'mongoose'; import Message from './models/Message'; import dotenv from 'dotenv'; +import messageRouters from '../dist/routes/messageRoutes'; + +// Load environment variables from .env file dotenv.config(); + // Connect to MongoDB mongoose.connect(`mongodb://${process.env.MONGODB_USER}:${process.env.MONGODB_USER_PASSWORD}@localhost:27017/${process.env.MONGO_INITDB_DATABASE}`) .then(() => console.log('Connected to MongoDB')) @@ -15,6 +19,11 @@ const app = express(); const server = http.createServer(app); const io = new SocketIOServer(server); +// Configure Express to serve static files from the public folder +app.use(express.static('../front/public/')); +app.use(express.json()); +app.use(messageRouters); + const PORT = 3001; // Start the server @@ -58,4 +67,3 @@ io.on('connection', (socket) => { }); }); -app.use(express.static('../front/public/')); diff --git a/back/src/models/Users.ts b/back/src/models/Users.ts new file mode 100644 index 0000000..a805229 --- /dev/null +++ b/back/src/models/Users.ts @@ -0,0 +1,18 @@ +import mongoose, { Document, Schema } from "mongoose"; + +// Define an interface that represents a document in MongoDB +interface IUser extends Document { + username: string; + password: string; +} + +// Define a schema that maps to a MongoDB collection and defines the shape of the documents within that collection +const UserSchema: Schema = new Schema({ + username: { type: String, required: true }, + password: { type: String, required: true }, +}); + +// Define a model for interacting with the database +const User = mongoose.model("User", UserSchema); + +export default User; From bfe25d84b07e77156f652cf602ddfd374b586727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20BRAVO?= <96313051+loicBRAVO@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:39:29 +0100 Subject: [PATCH 4/4] Refactor MongoDB connection and update code formatting --- back/src/index.ts | 55 +++++++++++++++++--------------- back/src/routes/messageRoutes.ts | 35 ++++++++++++++++++++ back/src/routes/usersRoutes.ts | 27 ++++++++++++++++ 3 files changed, 91 insertions(+), 26 deletions(-) create mode 100644 back/src/routes/messageRoutes.ts create mode 100644 back/src/routes/usersRoutes.ts diff --git a/back/src/index.ts b/back/src/index.ts index a7bd2be..25c4227 100644 --- a/back/src/index.ts +++ b/back/src/index.ts @@ -1,26 +1,28 @@ -import express from 'express'; -import http from 'http'; -import { Server as SocketIOServer } from 'socket.io'; -import mongoose from 'mongoose'; -import Message from './models/Message'; -import dotenv from 'dotenv'; -import messageRouters from '../dist/routes/messageRoutes'; +import express from "express"; +import http from "http"; +import { Server as SocketIOServer } from "socket.io"; +import mongoose from "mongoose"; +import Message from "./models/Message"; +import dotenv from "dotenv"; +import messageRouters from "./routes/messageRoutes"; // Load environment variables from .env file dotenv.config(); - // Connect to MongoDB -mongoose.connect(`mongodb://${process.env.MONGODB_USER}:${process.env.MONGODB_USER_PASSWORD}@localhost:27017/${process.env.MONGO_INITDB_DATABASE}`) - .then(() => console.log('Connected to MongoDB')) - .catch((err: any) => console.error('Could not connect to MongoDB', err)); +mongoose + .connect( + `mongodb://${process.env.MONGODB_USER}:${process.env.MONGODB_USER_PASSWORD}@localhost:27017/${process.env.MONGO_INITDB_DATABASE}` + ) + .then(() => console.log("Connected to MongoDB")) + .catch((err: any) => console.error("Could not connect to MongoDB", err)); const app = express(); const server = http.createServer(app); const io = new SocketIOServer(server); // Configure Express to serve static files from the public folder -app.use(express.static('../front/public/')); +app.use(express.static("../front/public/")); app.use(express.json()); app.use(messageRouters); @@ -31,19 +33,21 @@ server.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); -io.on('connection', (socket) => { - console.log('User connected:', socket.id); +io.on("connection", (socket) => { + console.log("User connected:", socket.id); // Listen for incoming chat messages - socket.on('chat message', async (data) => { - console.log('Received message:', data); + socket.on("chat message", async (data) => { + console.log("Received message:", data); // Prepare the message document according to the updated schema const messageDocument = { - messages: [{ - timestamp: new Date(), - content: data.message, - }] + messages: [ + { + timestamp: new Date(), + content: data.message, + }, + ], }; // Instantiate the Message model with the document @@ -52,18 +56,17 @@ io.on('connection', (socket) => { try { // Save the message document to MongoDB await messageModel.save(); - console.log('Message saved to the database'); + console.log("Message saved to the database"); // Broadcast the message to all connected clients - io.emit('chat message', data); + io.emit("chat message", data); } catch (err) { - console.error('Error saving message to database:', err); + console.error("Error saving message to database:", err); } }); // Listen for user disconnection - socket.on('disconnect', () => { - console.log('User disconnected:', socket.id); + socket.on("disconnect", () => { + console.log("User disconnected:", socket.id); }); }); - diff --git a/back/src/routes/messageRoutes.ts b/back/src/routes/messageRoutes.ts new file mode 100644 index 0000000..ebf4dda --- /dev/null +++ b/back/src/routes/messageRoutes.ts @@ -0,0 +1,35 @@ +import express, { Request, Response } from "express"; +import MessageModel from "../models/Message"; + +const router = express.Router(); + +// Route pour récupérer tous les messages +router.get("/messages", async (req: Request, res: Response) => { + try { + const messages = await MessageModel.find({}); + res.json(messages); + } catch (error) { + res.status(500).json({ message: (error as Error).message }); + } +}); + +// Route pour ajouter un nouveau message +router.post("/messages", async (req: Request, res: Response) => { + const newMessage = { + timestamp: new Date(), // ou req.body.timestamp + content: req.body.content, + }; + + try { + const updatedDocument = await MessageModel.findOneAndUpdate( + {}, + { $push: { messages: newMessage } }, + { new: true, upsert: true } + ); + res.status(201).json(updatedDocument); + } catch (error) { + res.status(400).json({ message: (error as Error).message }); + } +}); + +export default router; diff --git a/back/src/routes/usersRoutes.ts b/back/src/routes/usersRoutes.ts new file mode 100644 index 0000000..c2ba644 --- /dev/null +++ b/back/src/routes/usersRoutes.ts @@ -0,0 +1,27 @@ +import express, { Request, Response } from "express"; +import UserModel from "../models/Users"; + +const router = express.Router(); + +// Route pour créer un nouvel utilisateur +router.post("/users", async (req: Request, res: Response) => { + const newUser = new UserModel({ + username: req.body.username, + password: req.body.password, // Vous devriez hasher le mot de passe + }); + + try { + const savedUser = await newUser.save(); + res.status(201).json(savedUser); + } catch (error) { + res.status(400).json({ message: (error as Error).message }); + } +}); + +// Route pour authentifier un utilisateur +// Ajoutez ici la logique d'authentification +router.post("/users/authenticate", async (req: Request, res: Response) => { + // Implémentation de l'authentification +}); + +export default router;