Merge branch 'frontend_test_general' into 'master'

Frontend test general

See merge request groupe100idee/chatless!1
This commit is contained in:
Yûki Vachot 2021-05-29 01:32:39 +02:00
commit 30e7faffbc
29 changed files with 283 additions and 559 deletions

View file

@ -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;

View file

@ -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: '',

View file

@ -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');

View file

@ -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;

View file

@ -1,6 +1,6 @@
const config = {
mongodbDatabase: 'chat',
mongodbHost: 'mongodb://mongodb-message:27020/',
mongodbHost: 'mongodb://127.0.0.1:27020/',
charset: 'utf8',
mongodbLogin: '',
mongodbPassword: '',

View file

@ -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 };

View file

@ -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);

View file

@ -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}/`);
});

View file

@ -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;

View file

@ -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=="
}
}
},

View file

@ -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"
},

View file

@ -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,
}
];

View file

@ -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 { }

View file

@ -1,52 +1,25 @@
<div class="container-fluid" >
<div class="row">
<!DOCTYPE html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
body { margin: 0; padding-bottom: 3rem; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }
<div class="col-md-4">
#form { background: rgba(0, 0, 0, 0.15); padding: 0.25rem; position: fixed; bottom: 0; left: 0; right: 0; display: flex; height: 3rem; box-sizing: border-box; backdrop-filter: blur(10px); }
#input { border: none; padding: 0 1rem; flex-grow: 1; border-radius: 2rem; margin: 0.25rem; }
#input:focus { outline: none; }
#form > button { background: #333; border: none; padding: 0 1rem; margin: 0.25rem; border-radius: 3px; outline: none; color: #fff; }
<div class="user-list-card">
<div class="user-card"
>
<!---->
<img src="../../assets/image/user.png" height="25" width="25"/>
<p class="username"></p>
</div>
</div>
</div>
<div class="col-md-8">
<div class="chat-container">
<ng-container *ngIf="selectedUser">
<div class="chat-header">
<p class="username">{{selectedUser?.name}}</p>
</div>
<div class="chat-body">
<div *ngFor="let item of messageArray">
<span><strong>{{item.user}} : </strong> {{item.message}}</span>
</div>
</div>
<div class="chat-footer">
<div class="row">
<div class="col-md-10">
<div class="form-group mb-0">
<input type="text" placeholder="Entrez votre message" class="form-control"
[(ngModel)]="messageText"/>
</div>
</div>
<div class="col-md-2 text-center align-self-center">
<button class="btn btn-primary btn-bm px-3 " (click)="sendMessage()">Envoyer</button>
</div>
</div>
</div>
</ng-container>
</div>
</div>
</div>
</div>
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages > li { padding: 0.5rem 1rem; }
#messages > li:nth-child(odd) { background: #efefef; }
</style>
</head>
<body>
<ul #ulMessages id="messages">
</ul>
<form id="form" action="">
<input id="input" autocomplete="off" name="message" [(ngModel)]="msg"/><button (click)="sendButtonClick()">Send</button>
</form>
</body>
</html>

View file

@ -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<userList>();
// @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() {
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', '<li><span class="text-danger">'+data.message+'</span></li>');
}
ngOnInit(): void {
this.MS.sendMessage('Cours/CoursGet', {}).subscribe( send => {
console.log(send.data);
this.dataSource.data = send.data as userList[];
else{
this.ulMsg.nativeElement.insertAdjacentHTML('beforeend','<li><span class="text-primary">['+this.pipe.transform(data.date, 'dd/MM/yyyy HH:MM:ss')+'] </span><span class="text-success">'+data.username+' </span>:<span class="text-secondary"> '+data.message+'</span></li>');
}
}
}
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;
}

View file

@ -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);

View file

@ -1 +0,0 @@
<p>navbar works!</p>

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NavbarComponent } from './navbar.component';
describe('NavbarComponent', () => {
let component: NavbarComponent;
let fixture: ComponentFixture<NavbarComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ NavbarComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(NavbarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -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 {
}
}

View file

@ -1,55 +0,0 @@
<div class="container-fluid" >
<div class="row">
<div class="col-md-4">
<div class="user-list-card">
<div class="user-card"
>
<!---->
<img src="../../assets/image/user.png" height="25" width="25"/>
<p class="username"></p>
</div>
</div>
</div>
<div class="col-md-8">
<div class="chat-container">
<ng-container *ngIf="selectedUser">
<div class="chat-header">
<p class="username">{{selectedUser?.name}}</p>
</div>
<div class="chat-body">
<div *ngFor="let item of messageArray"
>
<!---->
<p class="message-container">{{item?.message}}</p>
</div>
</div>
<div class="chat-footer">
<div class="row">
<div class="col-md-10">
<div class="form-group mb-0">
<input type="text" placeholder="Entrez votre message" class="form-control"
[(ngModel)]="messageText" (keyup)="$event.keyCode === 13 && sendMessage()"/>
</div>
</div>
<div class="col-md-2 text-center align-self-center">
<button class="btn btn-primary btn-bm px-3 " (click)="sendMessage()">Envoyer</button>
</div>
</div>
</div>
</ng-container>
</div>
</div>
</div>
</div>

View file

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PrivateComponent } from './private.component';
describe('PrivateComponent', () => {
let component: PrivateComponent;
let fixture: ComponentFixture<PrivateComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PrivateComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PrivateComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -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<userList>();
// @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;
}

View file

@ -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 = '';
}
setUrl(url: string){
this.url = url;
this.setSocket();
}
setRoom(room: string){
this.room = room;
}
setSocket(){
this.socket = io(this.url, {
withCredentials: true
});
}
sendMessage(username: string | null, room: string, message: string) {
// @ts-ignore
joinRoom(data): void {
this.socket.emit('join', data);
this.socket.emit(room, {
username: username,
date: new Date(),
room: room,
message: message
});
}
onNewMessage(room: string): Observable<ChatInfo[]> {
return new Observable(observer => {
// @ts-ignore
sendMessage(data): void{
this.socket.emit('message', data);
}
getMessage(): Observable<any> {
return new Observable<{user: string, message: string}>(observer => {
this.socket.on('new message', (data) => {
this.socket.on(room, (data: ChatInfo[]) => {
console.log(data);
observer.next(data);
});
return () => {
this.socket.disconnect();
}
});
}
newUserJoined()
{
let observable = new Observable<{user:String, message:String}>(observer=>{
this.socket.on('new user joined', (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));
}
}

View file

@ -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'
};
/*