diff --git a/backend/service-authentication/keys/jwtRS256.key b/backend/keys/jwtRS256.key similarity index 100% rename from backend/service-authentication/keys/jwtRS256.key rename to backend/keys/jwtRS256.key diff --git a/backend/service-authentication/keys/jwtRS256.key.pub b/backend/keys/jwtRS256.key.pub similarity index 100% rename from backend/service-authentication/keys/jwtRS256.key.pub rename to backend/keys/jwtRS256.key.pub diff --git a/backend/service-authentication/keys/jwtRS256.sh b/backend/keys/jwtRS256.sh similarity index 100% rename from backend/service-authentication/keys/jwtRS256.sh rename to backend/keys/jwtRS256.sh diff --git a/backend/service-authentication/auth.js b/backend/service-authentication/auth.js index 172742f..c47a3ef 100644 --- a/backend/service-authentication/auth.js +++ b/backend/service-authentication/auth.js @@ -21,8 +21,8 @@ module.exports.setSessionCookie = setSessionCookie; // de session. Si ce dernier n'existe pas, on renvoie // l'ID -1. function getUserId(session) { - if (typeof session.userId === 'undefined') return -1; - return session.userId; + if (typeof session.username === 'undefined') return -1; + return session.username; } module.exports.getUserId = getUserId; diff --git a/backend/service-authentication/config.js b/backend/service-authentication/config.js index 4e951d0..da5ca03 100644 --- a/backend/service-authentication/config.js +++ b/backend/service-authentication/config.js @@ -1,7 +1,7 @@ const config = { // paramètres de connexion à la base de données mongodbDatabase: 'chat', - mongodbHost: 'mongodb://mongodb-authentication:27017/', + mongodbHost: 'mongodb://127.0.0.1:27017/', charset: 'utf8', mongodbLogin: '', mongodbPassword: '', diff --git a/backend/service-authentication/server.js b/backend/service-authentication/server.js index a15ce7a..7f226dc 100644 --- a/backend/service-authentication/server.js +++ b/backend/service-authentication/server.js @@ -20,6 +20,7 @@ mongoConnect.connectToServer(function( err, client ) { const register = require('./register'); const queries = require('./mongodbQueries'); + queries.register('Server','admin'); queries.register('khai','test'); queries.register('wilfried','test'); queries.register('yuki','test'); diff --git a/backend/service-authentication/sessionJWT.js b/backend/service-authentication/sessionJWT.js index 90133d1..ebec454 100644 --- a/backend/service-authentication/sessionJWT.js +++ b/backend/service-authentication/sessionJWT.js @@ -1,11 +1,12 @@ const sessionJWT = require ('jsonwebtoken'); const fs = require ('fs'); + // renvoie un nouveau token JWT -function createSessionJWT (userId) { +function createSessionJWT (username) { // ci-dessous, on met en place le cookie de session JWT : // 1/ on recupere notre clef privee - const RSA_PRIVATE_KEY = fs.readFileSync('./keys/jwtRS256.key'); + const RSA_PRIVATE_KEY = fs.readFileSync('../keys/jwtRS256.key'); // 2/ on signe un token JWT. Le payload est l'identifiant de // l'utilisateur ainsi qu'une date d'expiration à mi-parcours : @@ -18,7 +19,7 @@ function createSessionJWT (userId) { // session. const jwtToken = sessionJWT.sign( { - userId: userId, + username: username, midExp: Math.floor(Date.now() / 1000) + 1800 // validité: 30mn }, RSA_PRIVATE_KEY, @@ -40,14 +41,15 @@ function createSessionCookie(req, res, payload) { // midExp, alors le cookie est encore valide et on peut le renvoyer. Sinon, // on doit recalculer un nouveau cookie. let jwtToken = ''; - if ((typeof payload.userId !== 'undefined') && + if ((typeof payload.username !== 'undefined') && (typeof payload.midExp !== 'undefined') && (Math.floor(Date.now() / 1000) <= payload.midExp)) { - jwtToken = req.cookies.SESSIONID; + jwtToken = req.headers.cookie; } else { - // on crée un nouveau cookie - jwtToken = createSessionJWT(payload.userId); + // on crée + // un nouveau cookie + jwtToken = createSessionJWT(payload.username); } // on renvoie le cookie au client @@ -63,14 +65,13 @@ module.exports.createSessionCookie = createSessionCookie; function decodeSessionCookie(req) { // si l'on n'a pas de cookie de session, on renvoie une session avec vide, // avec juste un userId à -1 - console.log(req.cookies); - if (typeof req.cookies.SESSIONID === 'undefined') { - return { userId: -1 }; - } - const sessionid = req.cookies.SESSIONID; + if (typeof req.headers.cookie === 'undefined') { + return { username: -1 }; + } + const sessionid = req.headers.cookie.replace('SESSIONID=',''); // on lit la clef publique - const RSA_PUBLIC_KEY = fs.readFileSync('./keys/jwtRS256.key.pub'); + const RSA_PUBLIC_KEY = fs.readFileSync('../keys/jwtRS256.key.pub'); // on récupère les données du cookie try { @@ -81,7 +82,7 @@ function decodeSessionCookie(req) { return token; } catch (err) { - return {userId: -1}; + return {username: err}; } } module.exports.decodeSessionCookie = decodeSessionCookie; diff --git a/backend/service-message/config.js b/backend/service-message/config.js index 612edc0..8b1fed7 100644 --- a/backend/service-message/config.js +++ b/backend/service-message/config.js @@ -1,6 +1,6 @@ const config = { mongodbDatabase: 'chat', - mongodbHost: 'mongodb://mongodb-message:27020/', + mongodbHost: 'mongodb://127.0.0.1:27020/', charset: 'utf8', mongodbLogin: '', mongodbPassword: '', diff --git a/backend/service-message/message.js b/backend/service-message/message.js deleted file mode 100644 index 05714bc..0000000 --- a/backend/service-message/message.js +++ /dev/null @@ -1,13 +0,0 @@ -// renvoie un message au format JSON. On a besoin de passer en paramètre -// res, la réponse que l'on envoie au client (Angular). Le paramètre -// data est un objet JavaScript. Globalement, cette fonction est -// équivalente au "echo json_encode(data);" que vous utilisiez en PHP -function sendMessage (res, data) { - res.json ({ status: 'ok', data: data }); -} - -function sendError (res, reason) { - res.json ({ status: 'error', data: {reason: reason }}); -} - -module.exports = { sendMessage, sendError }; diff --git a/backend/service-message/mongodb-message.js b/backend/service-message/mongodb-message.js index 5b5ff65..324d34d 100644 --- a/backend/service-message/mongodb-message.js +++ b/backend/service-message/mongodb-message.js @@ -1,6 +1,6 @@ const config = require('./config'); const mongoose = require( 'mongoose' ); -const url = config.mongodbHost; +const url = config.mongodbHost+config.mongodbDatabase; mongoose.connect(url,({useNewUrlParser: true, useUnifiedTopology: true})).then( function(){ console.log('mongodb-message connected '+mongoose.connection.readyState); @@ -8,7 +8,6 @@ mongoose.connect(url,({useNewUrlParser: true, useUnifiedTopology: true})).then( console.log('error : '+err); }); - const schemaMessage = mongoose.Schema({ username:{ type: String, @@ -26,7 +25,7 @@ const schemaMessage = mongoose.Schema({ type: String, required: true } -}); +},{ versionKey: false }); const messages = mongoose.model(config.mongodbMessages, schemaMessage); diff --git a/backend/service-message/server.js b/backend/service-message/server.js index 8e8508e..bb685f7 100644 --- a/backend/service-message/server.js +++ b/backend/service-message/server.js @@ -5,50 +5,59 @@ const cors = require ('cors'); const cookieParser = require('cookie-parser'); const auth = require ('./auth'); const bodyParser = require ('body-parser'); -const {sendError, sendMessage} = require ('./message'); const messages = require('./mongodb-message'); const app = express(); const server = http.createServer(app); -const io = new Server(server); -const port = process.env.PORT || 3000; +const io = new Server(server, { + cors: { + origin: "http://127.0.0.1:4200", + methods: ["GET", "POST"], + credentials: true + } +}); +const port = process.env.PORT || 3001; app.use(bodyParser.json()); app.use(cors({origin: 'http://127.0.0.1:4200', credentials: true})); app.use(cookieParser()); -io.use(function(socket, next){ - const session = auth.getSession(socket.request); - const getUsername = auth.getUsername(session); - if (getUsername === -1) { - //sendError(res, 'not authenticated'); - } - auth.setSessionCookie(socket.request, socket.request.res || {}, next); -}); app.get('/', (req, res) => { res.sendFile(__dirname + '/index.html'); }); io.on('connection',socket => { - let users = {} + + let users = {}; const session = auth.getSession(socket.request); const getUsername = auth.getUsername(session); - + if (getUsername === -1) { + socket.emit('error','not authenticated'); + } console.log(`${getUsername} joined the chat.`); - socket.broadcast.emit('general',`${getUsername} joined the chat.`); + socket.broadcast.emit('general',[{ + username: 'Server', + date: new Date(), + channel: 'general', + message: `${getUsername} joined the chat.` + }]); users[socket.id] = getUsername; - messages.find({},(err, res) => { + messages.find({}, {'_id':0},{sort: {'date':1}},(err, res) => { if(err) throw err; if(res.length > 0){ - const savedChat = res; - socket.emit('general',savedChat); + //console.log(res, res.length); + socket.emit('general',res); } + socket.emit('general',[{ + username: 'Server', + date: new Date(), + channel: 'general', + message: `${getUsername} joined the chat.` + }]); }); socket.on('general',function(data){ - socket.broadcast.emit('general',data); - const username = data.username; const date = Date.now(); const channel = 'general'; @@ -62,22 +71,20 @@ io.on('connection',socket => { } ]).then(function(){ console.log(data, "inserted"); + socket.broadcast.emit('general',[data]); + socket.emit('general',[data]); }).catch(function(error){ console.log("error",error); }); }); - socket.on('typing',(user)=>{ - socket.broadcast.emit('notifyTyping',user) - }) - socket.on("disconnect", function() { - console.log(`${socket.id} left the chat.`); + console.log(`${getUsername} left the chat.`); }); }); server.listen(port, () => { - console.log('listening on *:3000'); + console.log(`listening on *:${port}/`); }); \ No newline at end of file diff --git a/backend/service-message/sessionJWT.js b/backend/service-message/sessionJWT.js index 7372845..ebec454 100644 --- a/backend/service-message/sessionJWT.js +++ b/backend/service-message/sessionJWT.js @@ -1,11 +1,12 @@ const sessionJWT = require ('jsonwebtoken'); const fs = require ('fs'); + // renvoie un nouveau token JWT -function createSessionJWT (userId) { +function createSessionJWT (username) { // ci-dessous, on met en place le cookie de session JWT : // 1/ on recupere notre clef privee - const RSA_PRIVATE_KEY = fs.readFileSync('./keys/jwtRS256.key'); + const RSA_PRIVATE_KEY = fs.readFileSync('../keys/jwtRS256.key'); // 2/ on signe un token JWT. Le payload est l'identifiant de // l'utilisateur ainsi qu'une date d'expiration à mi-parcours : @@ -18,7 +19,7 @@ function createSessionJWT (userId) { // session. const jwtToken = sessionJWT.sign( { - userId: userId, + username: username, midExp: Math.floor(Date.now() / 1000) + 1800 // validité: 30mn }, RSA_PRIVATE_KEY, @@ -40,14 +41,15 @@ function createSessionCookie(req, res, payload) { // midExp, alors le cookie est encore valide et on peut le renvoyer. Sinon, // on doit recalculer un nouveau cookie. let jwtToken = ''; - if ((typeof payload.userId !== 'undefined') && + if ((typeof payload.username !== 'undefined') && (typeof payload.midExp !== 'undefined') && (Math.floor(Date.now() / 1000) <= payload.midExp)) { - jwtToken = req.cookies.SESSIONID; + jwtToken = req.headers.cookie; } else { - // on crée un nouveau cookie - jwtToken = createSessionJWT(payload.userId); + // on crée + // un nouveau cookie + jwtToken = createSessionJWT(payload.username); } // on renvoie le cookie au client @@ -63,13 +65,13 @@ module.exports.createSessionCookie = createSessionCookie; function decodeSessionCookie(req) { // si l'on n'a pas de cookie de session, on renvoie une session avec vide, // avec juste un userId à -1 - if (typeof req.cookies.SESSIONID === 'undefined') { - return { userId: -1 }; - } - const sessionid = req.cookies.SESSIONID; + if (typeof req.headers.cookie === 'undefined') { + return { username: -1 }; + } + const sessionid = req.headers.cookie.replace('SESSIONID=',''); // on lit la clef publique - const RSA_PUBLIC_KEY = fs.readFileSync('./keys/jwtRS256.key.pub'); + const RSA_PUBLIC_KEY = fs.readFileSync('../keys/jwtRS256.key.pub'); // on récupère les données du cookie try { @@ -80,7 +82,7 @@ function decodeSessionCookie(req) { return token; } catch (err) { - return {userId: -1}; + return {username: err}; } } module.exports.decodeSessionCookie = decodeSessionCookie; diff --git a/frontend/package-lock.json b/frontend/package-lock.json index f44d99e..adb6a9b 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -12,6 +12,23 @@ "requires": { "@angular-devkit/core": "12.0.1", "rxjs": "6.6.7" + }, + "dependencies": { + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } } }, "@angular-devkit/build-angular": { @@ -87,6 +104,23 @@ "webpack-dev-server": "3.11.2", "webpack-merge": "5.7.3", "webpack-subresource-integrity": "1.5.2" + }, + "dependencies": { + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } } }, "@angular-devkit/build-optimizer": { @@ -108,6 +142,23 @@ "requires": { "@angular-devkit/architect": "0.1200.1", "rxjs": "6.6.7" + }, + "dependencies": { + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } } }, "@angular-devkit/core": { @@ -122,6 +173,23 @@ "magic-string": "0.25.7", "rxjs": "6.6.7", "source-map": "0.7.3" + }, + "dependencies": { + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } } }, "@angular-devkit/schematics": { @@ -133,6 +201,23 @@ "@angular-devkit/core": "12.0.1", "ora": "5.4.0", "rxjs": "6.6.7" + }, + "dependencies": { + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } } }, "@angular/animations": { @@ -5620,6 +5705,15 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5628,6 +5722,12 @@ "requires": { "has-flag": "^4.0.0" } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true } } }, @@ -9896,17 +9996,17 @@ } }, "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.1.0.tgz", + "integrity": "sha512-gCFO5iHIbRPwznl6hAYuwNFld8W4S2shtSJIqG27ReWXo9IWrCyEICxUA+6vJHwSR/OakoenC4QsDxq50tzYmw==", "requires": { - "tslib": "^1.9.0" + "tslib": "~2.1.0" }, "dependencies": { "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" } } }, diff --git a/frontend/package.json b/frontend/package.json index 3d9e707..ad847c4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -25,7 +25,8 @@ "@types/socket.io-client": "^3.0.0", "bootstrap": "^4.6.0", "jquery": "^3.6.0", - "rxjs": "~6.6.0", + "rxjs": "^7.1.0", + "socket.io-client": "^4.1.2", "tslib": "^2.1.0", "zone.js": "~0.11.4" }, diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts index e9d2b65..d5c32ae 100644 --- a/frontend/src/app/app-routing.module.ts +++ b/frontend/src/app/app-routing.module.ts @@ -1,8 +1,7 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; -import {AppComponent} from "./app.component"; import {LoginComponent} from "./login/login.component"; -import {PrivateComponent} from "./private/private.component"; +import {GeneralComponent} from "./general/general.component"; const routes: Routes = [ { @@ -10,8 +9,8 @@ const routes: Routes = [ component: LoginComponent, }, { - path: 'private', - component: PrivateComponent, + path: 'general', + component: GeneralComponent, } ]; diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index 15f4949..ce86a8a 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -2,24 +2,18 @@ import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import {HttpClientModule} from "@angular/common/http"; import {FormsModule, ReactiveFormsModule} from "@angular/forms"; - - import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { LoginComponent } from './login/login.component'; import { GeneralComponent } from './general/general.component'; -import { PrivateComponent } from './private/private.component'; -import { NavbarComponent } from './navbar/navbar.component'; -import {CommonModule} from "@angular/common"; +import {CommonModule, DatePipe} from "@angular/common"; @NgModule({ declarations: [ AppComponent, LoginComponent, - GeneralComponent, - PrivateComponent, - NavbarComponent + GeneralComponent ], imports: [ BrowserModule, @@ -27,9 +21,9 @@ import {CommonModule} from "@angular/common"; FormsModule, CommonModule, ReactiveFormsModule, - AppRoutingModule + AppRoutingModule, ], - providers: [], + providers: [DatePipe], bootstrap: [AppComponent] }) export class AppModule { } diff --git a/frontend/src/app/general/general.component.html b/frontend/src/app/general/general.component.html index 96d610a..21f47dc 100644 --- a/frontend/src/app/general/general.component.html +++ b/frontend/src/app/general/general.component.html @@ -1,52 +1,25 @@ -
-
+ + + + Socket.IO chat + + + + +
+ +
+ + diff --git a/frontend/src/app/general/general.component.ts b/frontend/src/app/general/general.component.ts index e6b5700..81e43b1 100644 --- a/frontend/src/app/general/general.component.ts +++ b/frontend/src/app/general/general.component.ts @@ -1,8 +1,7 @@ -import { Component, OnInit } from '@angular/core'; -import {ChatService} from "../services/chat/chat.service"; -import {AuthService} from "../services/auth/auth.service"; -import {MessageService} from "../services/message/message.service"; -import {MatTableDataSource} from "@angular/material/table"; +import {Component, ElementRef, Inject, Input, OnInit, ViewChild} from '@angular/core'; +import {ChatInfo, ChatService} from "../services/chat/chat.service"; +import {environment} from "../../environments/environment"; +import {DatePipe} from "@angular/common"; @Component({ selector: 'app-general', @@ -10,123 +9,42 @@ import {MatTableDataSource} from "@angular/material/table"; styleUrls: ['./general.component.scss'] }) export class GeneralComponent implements OnInit { - dataSource = new MatTableDataSource(); - // @ts-ignore - public user:String; - // @ts-ignore - public room:String; - // @ts-ignore - public messageText: string; - messageArray:Array<{user:String,message:String}> = []; - private storageArray = []; + + private username = sessionStorage.getItem('login'); + private room = 'general'; + public msg = ''; // @ts-ignore - public showScreen: boolean; - - // @ts-ignore - public password: string; - - // @ts-ignore - public selectedUser; + @ViewChild('ulMessages') ulMsg: ElementRef; + constructor(private chatservice: ChatService, private pipe: DatePipe) {} - constructor(private Auth: AuthService, - private chatService: ChatService, - private MS: MessageService - ) { - - - this.chatService.newUserJoined() - .subscribe(data=> this.messageArray.push(data)); - - - this.chatService.userLeftRoom() - .subscribe(data=>this.messageArray.push(data)); - - this.chatService.getMessage() - .subscribe(data=>this.messageArray.push(data)); - } - ngOnInit(): void { - this.MS.sendMessage('Cours/CoursGet', {}).subscribe( send => { - console.log(send.data); - this.dataSource.data = send.data as userList[]; - + ngOnInit() { + console.log('General working'); + this.chatservice.setUrl(environment.urlCG); + this.chatservice.setRoom(this.room); + this.chatservice.onNewMessage(this.room).subscribe((infos: ChatInfo[]) => { + for(let data of infos){ + if(data !== undefined && data.date !== undefined){ + if(data.username === 'Server'){ + this.ulMsg.nativeElement.insertAdjacentHTML('beforeend', '
  • '+data.message+'
  • '); + } + else{ + this.ulMsg.nativeElement.insertAdjacentHTML('beforeend','
  • ['+this.pipe.transform(data.date, 'dd/MM/yyyy HH:MM:ss')+'] '+data.username+' : '+data.message+'
  • '); + } + } + } + window.scrollTo(0, document.body.scrollHeight); }); - // this.chatService.getMessage() - // .subscribe((data: {user: string, message: string}) => { - // this.messageArray.push(data); - // if (this.room) { - // setTimeout( () => { - // this.storageArray = this.chatService.getStorage(); - // //@ts-ignore - // const storeIndex = this.storageArray.findIndex((storage) => storage.room === this.room); - // //@ts-ignore - // this.messageArray = this.storageArray[storeIndex].chats; - // }, 500); - // } - // }); - } - // selectUserHandler(password: string): void { - // //this.selectedUser = this.userList.find(user => user.password === password); - // this.room = this.selectedUser.room[this.currentUser.id]; - // this.messageArray = []; - // - // this.storageArray = this.chatService.getStorage(); - // // @ts-ignore - // const storeIndex = this.storageArray.findIndex((storage) => storage.room === this.room); - // - // if (storeIndex > -1) { - // // @ts-ignore - // this.messageArray = this.storageArray[storeIndex].chats; - // } - // - // // @ts-ignore - // this.join(this.currentUser.name, this.room); - // } - - join(username: string, room: string): void { - this.chatService.joinRoom({user: username, room: room}); + sendButtonClick(){ + console.log('Button working'); + if(this.msg && this.username){ + this.chatservice.sendMessage(this.username, this.room, this.msg); + console.log(this.username, this.room, this.msg); + this.msg = ''; + } } - - sendMessage() - { - this.chatService.sendMessage({user:this.user, room:this.room, message:this.messageText}); - - // this.storageArray = this.chatService.getStorage(); - // // @ts-ignore - // const storeIndex = this.storageArray.findIndex((storage) => storage.room === this.room); - // - // if (storeIndex > -1) { - // // @ts-ignore - // this.storageArray[storeIndex].chats.push({ - // user: this.currentUser.name, - // message: this.messageText - // }) - // } else { - // const updateStorage = { - // room: this.room, - // chats: [{ - // user: this.currentUser.name, - // message: this.messageText - // }] - // }; - // // @ts-ignore - // this.storageArray.push(updateStorage); - // } - // this.chatService.setStorage(this.storageArray); - // this.messageText = ''; - } - - - leave(){ - this.chatService.leaveRoom({login:this.dataSource.data, room:this.room}); - } - - -} -export interface userList { - login: string; } diff --git a/frontend/src/app/login/login.component.ts b/frontend/src/app/login/login.component.ts index 5ef93c3..b2c0c55 100644 --- a/frontend/src/app/login/login.component.ts +++ b/frontend/src/app/login/login.component.ts @@ -1,5 +1,4 @@ import { Component, OnInit } from '@angular/core'; -import {NgbModal} from '@ng-bootstrap/ng-bootstrap'; import {Router} from "@angular/router"; import {AuthService} from "../services/auth/auth.service"; @@ -10,7 +9,6 @@ import {AuthService} from "../services/auth/auth.service"; }) export class LoginComponent implements OnInit { - login = ''; password = ''; errorMessage = ''; @@ -27,7 +25,8 @@ export class LoginComponent implements OnInit { this.auth.sendAuthentication(this.login, this.password).subscribe(data => { this.auth.finalizeAuthentication(data); if (this.auth.islog === true) { - this.router.navigateByUrl('/private'); + sessionStorage.setItem('login', this.login); + this.router.navigateByUrl('/general'); } else { this.errorMessage = data.data.reason; console.log(this.errorMessage); diff --git a/frontend/src/app/navbar/navbar.component.html b/frontend/src/app/navbar/navbar.component.html deleted file mode 100644 index 6bbf8ee..0000000 --- a/frontend/src/app/navbar/navbar.component.html +++ /dev/null @@ -1 +0,0 @@ -

    navbar works!

    diff --git a/frontend/src/app/navbar/navbar.component.scss b/frontend/src/app/navbar/navbar.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/frontend/src/app/navbar/navbar.component.spec.ts b/frontend/src/app/navbar/navbar.component.spec.ts deleted file mode 100644 index f8ccd6f..0000000 --- a/frontend/src/app/navbar/navbar.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { NavbarComponent } from './navbar.component'; - -describe('NavbarComponent', () => { - let component: NavbarComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ NavbarComponent ] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(NavbarComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/frontend/src/app/navbar/navbar.component.ts b/frontend/src/app/navbar/navbar.component.ts deleted file mode 100644 index 6a9bec8..0000000 --- a/frontend/src/app/navbar/navbar.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-navbar', - templateUrl: './navbar.component.html', - styleUrls: ['./navbar.component.scss'] -}) -export class NavbarComponent implements OnInit { - - constructor() { } - - ngOnInit(): void { - } - -} diff --git a/frontend/src/app/private/private.component.html b/frontend/src/app/private/private.component.html deleted file mode 100644 index 775a86b..0000000 --- a/frontend/src/app/private/private.component.html +++ /dev/null @@ -1,55 +0,0 @@ -
    -
    - -
    - -
    -
    - - - -

    - -
    -
    - -
    -
    - -
    - -
    -

    {{selectedUser?.name}}

    -
    - -
    -
    - - -

    {{item?.message}}

    -
    -
    - - -
    -
    -
    -
    -
    diff --git a/frontend/src/app/private/private.component.scss b/frontend/src/app/private/private.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/frontend/src/app/private/private.component.spec.ts b/frontend/src/app/private/private.component.spec.ts deleted file mode 100644 index f2a3e2f..0000000 --- a/frontend/src/app/private/private.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { PrivateComponent } from './private.component'; - -describe('PrivateComponent', () => { - let component: PrivateComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ PrivateComponent ] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(PrivateComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/frontend/src/app/private/private.component.ts b/frontend/src/app/private/private.component.ts deleted file mode 100644 index b1a4812..0000000 --- a/frontend/src/app/private/private.component.ts +++ /dev/null @@ -1,123 +0,0 @@ -import {NgModule, Component, OnInit, Input} from '@angular/core'; -import {ChatService} from "../services/chat/chat.service"; -import {FormsModule, ReactiveFormsModule} from "@angular/forms"; -import {AuthService} from "../services/auth/auth.service"; -import {MessageService} from "../services/message/message.service"; -import {MatTableDataSource} from "@angular/material/table"; - - -@Component({ - selector: 'app-private', - templateUrl: './private.component.html', - styleUrls: ['./private.component.scss'] -}) -export class PrivateComponent implements OnInit { - - dataSource = new MatTableDataSource(); - // @ts-ignore - public roomId: string; - // @ts-ignore - public messageText: string; - public messageArray: {user: string, message: string}[] = []; - private storageArray = []; - - // @ts-ignore - public showScreen: boolean; - - // @ts-ignore - public password: string; - // @ts-ignore - public currentUser; - // @ts-ignore - public selectedUser; - - - - constructor( - private Auth: AuthService, - private chatService: ChatService, - private MS: MessageService - - ) { - } - - ngOnInit(): void { - this.MS.sendMessage('Cours/CoursGet', {}).subscribe( send => { - console.log(send.data); - this.dataSource.data = send.data as userList[]; - }); - - // this.chatService.getMessage() - // .subscribe((data: {user: string, message: string}) => { - // this.messageArray.push(data); - // if (this.roomId) { - // setTimeout( () => { - // this.storageArray = this.chatService.getStorage(); - // //@ts-ignore - // const storeIndex = this.storageArray.findIndex((storage) => storage.roomId === this.roomId); - // //@ts-ignore - // this.messageArray = this.storageArray[storeIndex].chats; - // }, 500); - // } - // }); - - } - - // selectUserHandler(login: string): void { - // this.login = login; - // this.selectedUser = this.userList.find(user => user.password === password); - // this.roomId = this.selectedUser.roomId[this.currentUser.id]; - // this.messageArray = []; - // - // // this.storageArray = this.chatService.getStorage(); - // // // @ts-ignore - // // const storeIndex = this.storageArray.findIndex((storage) => storage.roomId === this.roomId); - // // - // // if (storeIndex > -1) { - // // // @ts-ignore - // // this.messageArray = this.storageArray[storeIndex].chats; - // // } - // - // this.join(this.login); - // } - - join(username: string, roomId: string): void { - this.chatService.joinRoom({user: username}); - } - - sendMessage(): void { - this.chatService.sendMessage({ - user: this.currentUser.name, - message: this.messageText - }); - - // this.storageArray = this.chatService.getStorage(); - // // @ts-ignore - // const storeIndex = this.storageArray.findIndex((storage) => storage.roomId === this.roomId); - // - // if (storeIndex > -1) { - // // @ts-ignore - // this.storageArray[storeIndex].chats.push({ - // user: this.currentUser.name, - // message: this.messageText - // }) - // } else { - // const updateStorage = { - // roomId: this.roomId, - // chats: [{ - // user: this.currentUser.name, - // message: this.messageText - // }] - // }; - // // @ts-ignore - // this.storageArray.push(updateStorage); - // } - // this.chatService.setStorage(this.storageArray); - this.messageText = ''; - } - -} - -export interface userList { - login: string; -} diff --git a/frontend/src/app/services/chat/chat.service.ts b/frontend/src/app/services/chat/chat.service.ts index 7501961..19bffd5 100644 --- a/frontend/src/app/services/chat/chat.service.ts +++ b/frontend/src/app/services/chat/chat.service.ts @@ -1,75 +1,61 @@ import { Injectable } from '@angular/core'; -import { io, Socket } from "socket.io-client"; -import {Observable} from "rxjs"; +import { Observable } from 'rxjs'; +import { io, Socket } from 'socket.io-client'; + +export interface ChatInfo { + username: string, + date: Date, + room: string, + message: string +} + @Injectable({ providedIn: 'root' }) export class ChatService { - private socket: Socket; - private url = 'http://localhost:3000'; + private socket: Socket | undefined; + private url: string; + private room: string; constructor() { - this.socket = io(this.url); + this.url = ''; + this.room = ''; } - // @ts-ignore - joinRoom(data): void { - this.socket.emit('join', data); + setUrl(url: string){ + this.url = url; + this.setSocket(); } - // @ts-ignore - sendMessage(data): void{ - this.socket.emit('message', data); + setRoom(room: string){ + this.room = room; } - getMessage(): Observable { - return new Observable<{user: string, message: string}>(observer => { - this.socket.on('new message', (data) => { - observer.next(data); - }); - return () => { - this.socket.disconnect(); - } + setSocket(){ + this.socket = io(this.url, { + withCredentials: true }); } - newUserJoined() - { - let observable = new Observable<{user:String, message:String}>(observer=>{ - this.socket.on('new user joined', (data)=>{ + sendMessage(username: string | null, room: string, message: string) { + // @ts-ignore + this.socket.emit(room, { + username: username, + date: new Date(), + room: room, + message: message + }); + } + + onNewMessage(room: string): Observable { + return new Observable(observer => { + // @ts-ignore + this.socket.on(room, (data: ChatInfo[]) => { + console.log(data); observer.next(data); }); - return () => {this.socket.disconnect();} }); - - return observable; } - - // @ts-ignore - leaveRoom(data){ - this.socket.emit('leave',data); - } - - userLeftRoom(){ - let observable = new Observable<{user:String, message:String}>(observer=>{ - this.socket.on('left room', (data)=>{ - observer.next(data); - }); - return () => {this.socket.disconnect();} - }); - - return observable; - } - - getStorage() { - const storage = localStorage.getItem('chats'); - return storage ? JSON.parse(storage) : []; - } - - setStorage(data: any) { - localStorage.setItem('chats', JSON.stringify(data)); - } - } diff --git a/frontend/src/environments/environment.ts b/frontend/src/environments/environment.ts index 78b83a0..3397ef3 100644 --- a/frontend/src/environments/environment.ts +++ b/frontend/src/environments/environment.ts @@ -4,7 +4,8 @@ export const environment = { production: false, - urlCL: 'http://127.0.0.1:3000' + urlCL: 'http://127.0.0.1:3000', + urlCG: 'http://127.0.0.1:3001' }; /*