Compare commits
94 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ecd7867b0 | ||
|
|
438f478541 | ||
|
|
92d359b282 | ||
|
|
c9fb831fbb | ||
|
|
837a7391e6 | ||
|
|
6b9684c6e1 | ||
|
|
34a5f703ea | ||
|
|
75060a0997 | ||
|
|
785560b666 | ||
|
|
fa14a1c149 | ||
|
|
2a5bf74e0e | ||
|
|
1b30d725f1 | ||
|
|
c53c80d8a2 | ||
|
|
8d16fd0e73 | ||
|
|
9d5bba8f20 | ||
|
|
737b284865 | ||
|
|
c6716d9280 | ||
|
|
685a00db49 | ||
|
|
ae3c3456c5 | ||
|
|
febf812963 | ||
|
|
471225f7fa | ||
|
|
494565fecd | ||
|
|
9210ff9210 | ||
|
|
aa4fc113a1 | ||
|
|
fcf88e3cde | ||
|
|
5f6535e7c9 | ||
|
|
4e5197d4bb | ||
|
|
6b0cb128b2 | ||
|
|
7329ee5fe0 | ||
|
|
6c94581615 | ||
|
|
8213823e9f | ||
|
|
655eeada53 | ||
|
|
577abeb65c | ||
|
|
22b137931d | ||
|
|
95c08668f7 | ||
|
|
fe7b142a5c | ||
|
|
540539b9fa | ||
|
|
a126dab147 | ||
|
|
12b82d84c1 | ||
|
|
bfa6cc0855 | ||
|
|
8fe42de825 | ||
|
|
916ccddd7d | ||
|
|
62a4744e7d | ||
|
|
cdb90cdcfb | ||
|
|
b97e81d970 | ||
|
|
ee8ac3a18f | ||
|
|
9e1ce83b81 | ||
|
|
e271c9ea14 | ||
|
|
bb31981920 | ||
|
|
f36a48748b | ||
|
|
67368efd2d | ||
|
|
c84a17b47e | ||
|
|
aaf51632b4 | ||
|
|
d20c152c49 | ||
|
|
968e2b024a | ||
|
|
36016a1a0b | ||
|
|
c5406006da | ||
|
|
67a37d16ec | ||
|
|
64b35b5fe6 | ||
|
|
ed40b33b54 | ||
|
|
d103fec09c | ||
|
|
58c324ff42 | ||
|
|
06653deac7 | ||
|
|
105cbf18f6 | ||
|
|
7a19bfbe69 | ||
|
|
2d95b38a85 | ||
|
|
c00d9ba51d | ||
|
|
bc6aa6dd28 | ||
|
|
0533dae04a | ||
|
|
18eb60894c | ||
|
|
52583f1f43 | ||
|
|
374e000f5b | ||
|
|
68f48b0c09 | ||
|
|
ca057706a5 | ||
|
|
f11941590c | ||
|
|
7b351d8b09 | ||
|
|
5d46765145 | ||
|
|
e06c332bd1 | ||
|
|
50d06cc817 | ||
|
|
35f47457c2 | ||
|
|
ae0da17533 | ||
|
|
0625a3929f | ||
|
|
6818e0bb47 | ||
|
|
36e6596c78 | ||
|
|
0348ca1ecc | ||
|
|
aa2f6e0ecc | ||
|
|
6f7e465b86 | ||
|
|
4b8337c4f6 | ||
|
|
0034b66391 | ||
|
|
c652958324 | ||
|
|
5027493910 | ||
|
|
def91588a3 | ||
|
|
8547ebf403 | ||
|
|
c14c46a444 |
79 changed files with 5482 additions and 613 deletions
22
README.md
22
README.md
|
|
@ -1,5 +1,27 @@
|
||||||
**Projet Chat**
|
**Projet Chat**
|
||||||
|
|
||||||
|
**Instruction de lancement du Chat**
|
||||||
|
- `docker compose up`
|
||||||
|
- Puis se connecter en local sur `http://localhost:4200`
|
||||||
|
- Identifiants de connexion disponible :
|
||||||
|
- Username : cloud | Password : computing
|
||||||
|
- Username : wilfried | Password : test
|
||||||
|
- Username : yuki | Password : test
|
||||||
|
- Username : khai | Password : test
|
||||||
|
- Pour avoir un autre utilisateur connecté, il faut absolument avoir soit un autre navigateur soit un autre onglet en navigateur privé (pour cause d'identifiant de session)
|
||||||
|
|
||||||
|
Pour lancer le projet sans image docker, il est obligatoire de lancer plusieurs terminals pour le frontend et pour chaque
|
||||||
|
serveurs et avoir des images dockers mongodb.
|
||||||
|
A savoir:
|
||||||
|
- Terminal Frontend dans le dossier frontend : `ng serve`
|
||||||
|
- Terminal service-authentication dans le dossier service-authentication : `node server.js`
|
||||||
|
- Terminal service-message dans le dossier service-message : `node server.js`
|
||||||
|
- Terminal service-privateroom dans le dossier service-privateroom : `node server.js`
|
||||||
|
- Puis se connecter en local sur `http://localhost:4200`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**Instruction du professeur**
|
||||||
Le but du projet est de fournir un service de chat rudimentaire :
|
Le but du projet est de fournir un service de chat rudimentaire :
|
||||||
- Une interface utilisateur en web
|
- Une interface utilisateur en web
|
||||||
- Les utilisateurs peuvent s'enregistrer/se connecter/se déconnecter/changer leur mot de passe
|
- Les utilisateurs peuvent s'enregistrer/se connecter/se déconnecter/changer leur mot de passe
|
||||||
|
|
|
||||||
22
backend/service-authentication/changePassword.js
Normal file
22
backend/service-authentication/changePassword.js
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
const {sendError, sendMessage} = require ("./message");
|
||||||
|
const queries = require('./mongodbQueries');
|
||||||
|
|
||||||
|
async function changePassword (req,res) {
|
||||||
|
if (typeof req.body.username === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ username');
|
||||||
|
|
||||||
|
if (typeof req.body.password === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ password');
|
||||||
|
|
||||||
|
if (typeof req.body.newpassword === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ newpassword');
|
||||||
|
|
||||||
|
const change = await queries.changePasswordQuery(req.body.username, req.body.password, req.body.newpassword);
|
||||||
|
if (change){
|
||||||
|
return sendMessage(res, 'Le mot de passe a été changé.');
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return sendError(res, 'Mot de passe actuel incorrect ou erreur interne');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = changePassword;
|
||||||
|
|
@ -9,6 +9,7 @@ async function checkLogin (req,res) {
|
||||||
|
|
||||||
const result = await auth.authenticate(req, res);
|
const result = await auth.authenticate(req, res);
|
||||||
if (result === 1){
|
if (result === 1){
|
||||||
|
console.log(`${new Date()}] ${req.body.login} connected.`);
|
||||||
return sendMessage(res, true);
|
return sendMessage(res, true);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
const config = {
|
const config = {
|
||||||
// paramètres de connexion à la base de données
|
// paramètres de connexion à la base de données
|
||||||
mongodbDatabase: 'chat',
|
mongodbDatabase: 'chat',
|
||||||
mongodbHost: 'mongodb://127.0.0.1:27017/',
|
mongodbHost: 'mongodb://mongodb-authentication:27017/',
|
||||||
|
// mongodbHost: 'mongodb://127.0.0.1:27017/',
|
||||||
charset: 'utf8',
|
charset: 'utf8',
|
||||||
mongodbLogin: '',
|
mongodbLogin: '',
|
||||||
mongodbPassword: '',
|
mongodbPassword: '',
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ async function getUsers (req,res) {
|
||||||
return sendError(res, 'Vous n\'avez pas envoyé le champ username');
|
return sendError(res, 'Vous n\'avez pas envoyé le champ username');
|
||||||
|
|
||||||
const users = await queries.getUsersQuery(req.body.username);
|
const users = await queries.getUsersQuery(req.body.username);
|
||||||
console.log(users);
|
|
||||||
if (users){
|
if (users){
|
||||||
return sendMessage(res, users);
|
return sendMessage(res, users);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,15 @@ function register(login, password){
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
mongoDB.collection(config.mongodbUtilisateurs).updateOne(
|
mongoDB.collection(config.mongodbUtilisateurs).updateOne(
|
||||||
{'login': login},
|
{'login': login},
|
||||||
{$set: { 'login': login, 'password': password}},
|
{$setOnInsert: { 'login': login, 'password': password}},
|
||||||
{upsert:true},function(err,res){
|
{upsert:true},function(err,res){
|
||||||
//console.log(res);
|
//console.log(res);
|
||||||
if(res !== undefined){
|
if(res !== undefined){
|
||||||
resolve(res.upsertedCount === 1);
|
if(typeof res.upsertedId !== 'undefined'){
|
||||||
|
resolve(res.upsertedId);
|
||||||
|
}else{
|
||||||
|
resolve(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -42,3 +46,17 @@ function getUsersQuery(username){
|
||||||
}
|
}
|
||||||
module.exports.getUsersQuery = getUsersQuery
|
module.exports.getUsersQuery = getUsersQuery
|
||||||
|
|
||||||
|
function changePasswordQuery(login, password, newPassword){
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
mongoDB.collection(config.mongodbUtilisateurs).findOneAndUpdate(
|
||||||
|
{'login': login, 'password': password},
|
||||||
|
{$set: { 'login': login, 'password': newPassword}}
|
||||||
|
,function(err,res){
|
||||||
|
if(res !== undefined){
|
||||||
|
console.log(res);
|
||||||
|
resolve(res.lastErrorObject.n === 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
module.exports.changePasswordQuery = changePasswordQuery;
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,19 @@ const {sendError, sendMessage} = require ("./message");
|
||||||
const queries = require('./mongodbQueries');
|
const queries = require('./mongodbQueries');
|
||||||
|
|
||||||
async function register(req,res) {
|
async function register(req,res) {
|
||||||
if (typeof req.body.login === 'undefined')
|
if (typeof req.body.username === 'undefined')
|
||||||
return sendError(res, 'Vous n\'avez pas envoyé le champ login');
|
return sendError(res, 'Vous n\'avez pas envoyé le champ login');
|
||||||
if (typeof req.body.password === 'undefined')
|
if (typeof req.body.password === 'undefined')
|
||||||
return sendError(res, 'Vous n\'avez pas envoyé le champ password');
|
return sendError(res, 'Vous n\'avez pas envoyé le champ password');
|
||||||
|
|
||||||
|
|
||||||
const register = await queries.register(req.body.login, req.body.password);
|
const register = await queries.register(req.body.username, req.body.password);
|
||||||
if (register){
|
if (register){
|
||||||
console.log('Register : '+req.body.login);
|
console.log('Register : '+req.body.username);
|
||||||
return sendMessage(res, null);
|
return sendMessage(res, 'Successful registration');
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
return sendError(res, 'Error registering');
|
return sendError(res, 'Username already taken');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.exports = register;
|
module.exports = register;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ app.use(bodyParser.urlencoded({extended:true}));
|
||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
|
|
||||||
const cors = require('cors');
|
const cors = require('cors');
|
||||||
app.use(cors({origin: 'http://127.0.0.1:4200', credentials: true}));
|
app.use(cors({origin: 'http://localhost:4200', credentials: true}));
|
||||||
|
|
||||||
const mongoConnect = require('./mongodbConnect');
|
const mongoConnect = require('./mongodbConnect');
|
||||||
|
|
||||||
|
|
@ -18,6 +18,7 @@ mongoConnect.connectToServer(function( err, client ) {
|
||||||
if (err) console.log(err);
|
if (err) console.log(err);
|
||||||
const checkLogin = require('./checkLogin');
|
const checkLogin = require('./checkLogin');
|
||||||
const register = require('./register');
|
const register = require('./register');
|
||||||
|
const changePassword = require('./changePassword');
|
||||||
const getUsers = require('./getUsers');
|
const getUsers = require('./getUsers');
|
||||||
const queries = require('./mongodbQueries');
|
const queries = require('./mongodbQueries');
|
||||||
const auth = require('./auth');
|
const auth = require('./auth');
|
||||||
|
|
@ -26,6 +27,7 @@ mongoConnect.connectToServer(function( err, client ) {
|
||||||
queries.register('khai','test');
|
queries.register('khai','test');
|
||||||
queries.register('wilfried','test');
|
queries.register('wilfried','test');
|
||||||
queries.register('yuki','test');
|
queries.register('yuki','test');
|
||||||
|
queries.register('cloud','computing');
|
||||||
|
|
||||||
app.post('/verify:token', (req, res) => {
|
app.post('/verify:token', (req, res) => {
|
||||||
if(typeof req.body !== 'undefined'){
|
if(typeof req.body !== 'undefined'){
|
||||||
|
|
@ -46,7 +48,11 @@ mongoConnect.connectToServer(function( err, client ) {
|
||||||
getUsers(req,res);
|
getUsers(req,res);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.listen(port, () => {
|
app.post('/changePassword', (req, res) => {
|
||||||
|
changePassword(req,res);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(port, '0.0.0.0',() => {
|
||||||
console.log (`listening on port ${port}`);
|
console.log (`listening on port ${port}`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -4,17 +4,23 @@ function getSession (req, callback) {
|
||||||
if(typeof req.headers.cookie !== 'undefined'){
|
if(typeof req.headers.cookie !== 'undefined'){
|
||||||
request.post({
|
request.post({
|
||||||
headers: {'content-type' : 'application/x-www-form-urlencoded'},
|
headers: {'content-type' : 'application/x-www-form-urlencoded'},
|
||||||
url: 'http://127.0.0.1:3000/verify:token',
|
url: 'http://service-authentication:3000/verify:token',
|
||||||
body: 'sessionid='+req.headers.cookie.replace('SESSIONID=','')
|
body: 'sessionid='+req.headers.cookie.replace('SESSIONID=','')
|
||||||
},function (error, response, body) {
|
},function (error, response, body) {
|
||||||
const bodyJson = JSON.parse(body);
|
//console.log("body ; getSession auth message :",body);
|
||||||
if (bodyJson && bodyJson.status && bodyJson.data) {
|
if(typeof body !== 'undefined'){
|
||||||
if (bodyJson.status === 'ok') {
|
const bodyJson = JSON.parse(body);
|
||||||
return callback(bodyJson.data.token);
|
if (bodyJson && bodyJson.status && bodyJson.data) {
|
||||||
} else {
|
if (bodyJson.status === 'ok') {
|
||||||
return callback(bodyJson.data.reason);
|
return callback(bodyJson.data.token);
|
||||||
|
} else {
|
||||||
|
return callback(bodyJson.data.reason);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
return callback('Error');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return callback(undefined);
|
return callback(undefined);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
const config = {
|
const config = {
|
||||||
mongodbDatabase: 'chat',
|
mongodbDatabase: 'chat',
|
||||||
mongodbHost: 'mongodb://127.0.0.1:27020/',
|
mongodbHost: 'mongodb://mongodb-message:27017/',
|
||||||
|
// mongodbHost: 'mongodb://127.0.0.1:27020/',
|
||||||
charset: 'utf8',
|
charset: 'utf8',
|
||||||
mongodbLogin: '',
|
mongodbLogin: '',
|
||||||
mongodbPassword: '',
|
mongodbPassword: '',
|
||||||
|
|
@ -8,6 +9,3 @@ const config = {
|
||||||
mongodbMessages: 'messages'
|
mongodbMessages: 'messages'
|
||||||
};
|
};
|
||||||
module.exports = config;
|
module.exports = config;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,4 @@ const schemaMessage = mongoose.Schema({
|
||||||
|
|
||||||
const messages = mongoose.model(config.mongodbMessages, schemaMessage);
|
const messages = mongoose.model(config.mongodbMessages, schemaMessage);
|
||||||
|
|
||||||
// messages.find({},(err, messages) => {
|
|
||||||
// if(err) throw err;
|
|
||||||
// console.log(messages);
|
|
||||||
// });
|
|
||||||
|
|
||||||
module.exports = messages;
|
module.exports = messages;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ const app = express();
|
||||||
const server = http.createServer(app);
|
const server = http.createServer(app);
|
||||||
const io = new Server(server, {
|
const io = new Server(server, {
|
||||||
cors: {
|
cors: {
|
||||||
origin: "http://127.0.0.1:4200",
|
origin: "http://localhost:4200",
|
||||||
methods: ["GET", "POST"],
|
methods: ["GET", "POST"],
|
||||||
credentials: true
|
credentials: true
|
||||||
}
|
}
|
||||||
|
|
@ -19,31 +19,53 @@ const io = new Server(server, {
|
||||||
const port = process.env.PORT || 3001;
|
const port = process.env.PORT || 3001;
|
||||||
|
|
||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
app.use(cors({origin: 'http://127.0.0.1:4200', credentials: true}));
|
app.use(cors({origin: 'http://localhost:4200', credentials: true}));
|
||||||
app.use(cookieParser());
|
app.use(cookieParser());
|
||||||
|
|
||||||
// app.get('/', (req, res) => {
|
|
||||||
// res.sendFile(__dirname + '/index.html');
|
messages.insertMany([
|
||||||
// });
|
{
|
||||||
|
username: 'yuki',
|
||||||
|
date: new Date(),
|
||||||
|
channel: 'general',
|
||||||
|
message: 'Ceci est un message de test de la part de Yûki'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
username: 'wilfried',
|
||||||
|
date: new Date(),
|
||||||
|
channel: 'general',
|
||||||
|
message: 'Ceci est un message de test de la part de Wilfried'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
username: 'khai',
|
||||||
|
date: new Date(),
|
||||||
|
channel: 'general',
|
||||||
|
message: 'Ceci est un message de test de la part de Khai'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
username: 'cloud',
|
||||||
|
date: new Date(),
|
||||||
|
channel: 'general',
|
||||||
|
message: 'Ceci est un message à des fins de démonstration'
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
io.on('connection',socket => {
|
io.on('connection',socket => {
|
||||||
|
|
||||||
let users = {};
|
|
||||||
|
|
||||||
auth.getSession(socket.request, function(res){
|
auth.getSession(socket.request, function(res){
|
||||||
const getUsername = auth.getUsername(res);
|
const getUsername = auth.getUsername(res);
|
||||||
if (getUsername === -1) {
|
if (getUsername === -1) {
|
||||||
|
console.log('not authenticated',getUsername);
|
||||||
socket.send('error','not authenticated');
|
socket.send('error','not authenticated');
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
console.log(`${getUsername} joined the chat.`);
|
console.log(`${new Date()}] ${getUsername} joined the chat.`);
|
||||||
socket.broadcast.emit('general',[{
|
socket.broadcast.emit('general',[{
|
||||||
username: 'Server',
|
username: 'Server',
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
channel: 'general',
|
channel: 'general',
|
||||||
message: `${getUsername} joined the chat.`
|
message: `${getUsername} joined the chat.`
|
||||||
}]);
|
}]);
|
||||||
users[socket.id] = getUsername;
|
|
||||||
messages.find({}, {'_id':0},{sort: {'date':1}},(err, res) => {
|
messages.find({}, {'_id':0},{sort: {'date':1}},(err, res) => {
|
||||||
if(err) throw err;
|
if(err) throw err;
|
||||||
if(res.length > 0){
|
if(res.length > 0){
|
||||||
|
|
@ -60,7 +82,7 @@ io.on('connection',socket => {
|
||||||
|
|
||||||
socket.on('general',function(data){
|
socket.on('general',function(data){
|
||||||
const username = data.username;
|
const username = data.username;
|
||||||
const date = Date.now();
|
const date = data.date;
|
||||||
const channel = 'general';
|
const channel = 'general';
|
||||||
const message = data.message;
|
const message = data.message;
|
||||||
|
|
||||||
|
|
@ -71,7 +93,7 @@ io.on('connection',socket => {
|
||||||
message: message
|
message: message
|
||||||
}
|
}
|
||||||
]).then(function(){
|
]).then(function(){
|
||||||
console.log(data, "inserted");
|
//console.log(data, "inserted");
|
||||||
socket.broadcast.emit('general',[data]);
|
socket.broadcast.emit('general',[data]);
|
||||||
socket.emit('general',[data]);
|
socket.emit('general',[data]);
|
||||||
}).catch(function(error){
|
}).catch(function(error){
|
||||||
|
|
@ -81,12 +103,18 @@ io.on('connection',socket => {
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("disconnect", function() {
|
socket.on("disconnect", function() {
|
||||||
console.log(`${getUsername} left the chat.`);
|
console.log(`${new Date()}] ${getUsername} left the chat.`);
|
||||||
|
socket.broadcast.emit('general',[{
|
||||||
|
username: 'Server',
|
||||||
|
date: new Date(),
|
||||||
|
channel: 'general',
|
||||||
|
message: `${getUsername} left the chat.`
|
||||||
|
}]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
server.listen(port, () => {
|
server.listen(port,'0.0.0.0', () => {
|
||||||
console.log(`listening on *:${port}/`);
|
console.log (`listening on port ${port}`);
|
||||||
});
|
});
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
# syntax=docker/dockerfile:1
|
|
||||||
FROM node:current-slim
|
|
||||||
ENV NODE_ENV=production
|
|
||||||
WORKDIR /app-notification
|
|
||||||
COPY ["package.json", "package-lock.json*", "./"]
|
|
||||||
RUN npm install --production
|
|
||||||
COPY . .
|
|
||||||
CMD [ "node", "server.js" ]
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
# syntax=docker/dockerfile:1
|
|
||||||
FROM node:current-slim
|
FROM node:current-slim
|
||||||
ENV NODE_ENV=production
|
|
||||||
WORKDIR /app-privateroom
|
WORKDIR /app-privateroom
|
||||||
COPY ["package.json", "package-lock.json*", "./"]
|
COPY ["package.json", "package-lock.json*", "./"]
|
||||||
RUN npm install --production
|
RUN npm install
|
||||||
COPY . .
|
COPY . .
|
||||||
CMD [ "node", "server.js" ]
|
CMD node server.js
|
||||||
34
backend/service-privateroom/auth.js
Normal file
34
backend/service-privateroom/auth.js
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
const request = require('request');
|
||||||
|
|
||||||
|
function getSession (req, callback) {
|
||||||
|
if(typeof req.headers.cookie !== 'undefined'){
|
||||||
|
request.post({
|
||||||
|
headers: {'content-type' : 'application/x-www-form-urlencoded'},
|
||||||
|
url: 'http://service-authentication:3000/verify:token',
|
||||||
|
body: 'sessionid='+req.headers.cookie.replace('SESSIONID=','')
|
||||||
|
},function (error, response, body) {
|
||||||
|
//console.log("body ; getSession auth private :",body);
|
||||||
|
if(typeof body !== 'undefined'){
|
||||||
|
const bodyJson = JSON.parse(body);
|
||||||
|
if (bodyJson && bodyJson.status && bodyJson.data) {
|
||||||
|
if (bodyJson.status === 'ok') {
|
||||||
|
return callback(bodyJson.data.token);
|
||||||
|
} else {
|
||||||
|
return callback(bodyJson.data.reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return callback('Error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return callback(undefined);
|
||||||
|
}
|
||||||
|
module.exports.getSession = getSession;
|
||||||
|
|
||||||
|
function getUsername(session) {
|
||||||
|
if (typeof session === 'undefined' || typeof session.username === 'undefined') return -1;
|
||||||
|
return session.username;
|
||||||
|
}
|
||||||
|
module.exports.getUsername = getUsername;
|
||||||
15
backend/service-privateroom/config.js
Normal file
15
backend/service-privateroom/config.js
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
const config = {
|
||||||
|
mongodbDatabase: 'chat',
|
||||||
|
mongodbHost: 'mongodb://mongodb-privateroom:27017',
|
||||||
|
// mongodbHost: 'mongodb://127.0.0.1:27021/',
|
||||||
|
charset: 'utf8',
|
||||||
|
mongodbLogin: '',
|
||||||
|
mongodbPassword: '',
|
||||||
|
|
||||||
|
mongodbPrivatedMessages: 'privatedmessages',
|
||||||
|
mongodbConversations: 'conversations'
|
||||||
|
};
|
||||||
|
module.exports = config;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
13
backend/service-privateroom/message.js
Normal file
13
backend/service-privateroom/message.js
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
// 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 };
|
||||||
27
backend/service-privateroom/models/Conversation.js
Normal file
27
backend/service-privateroom/models/Conversation.js
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
const mongoose = require("mongoose");
|
||||||
|
const config = require("../config");
|
||||||
|
|
||||||
|
const url = config.mongodbHost+config.mongodbDatabase;
|
||||||
|
|
||||||
|
mongoose.connect(url,({useNewUrlParser: true, useUnifiedTopology: true})).then( function(){
|
||||||
|
console.log('mongodb-conversation connected '+mongoose.connection.readyState);
|
||||||
|
}).catch(function(err){
|
||||||
|
console.log('error : '+err);
|
||||||
|
});
|
||||||
|
|
||||||
|
const ConversationSchema = new mongoose.Schema(
|
||||||
|
{
|
||||||
|
owner: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
roomName: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
members: {
|
||||||
|
type: Array
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ timestamps: true, versionKey: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports = mongoose.model(config.mongodbConversations, ConversationSchema);
|
||||||
30
backend/service-privateroom/models/Message.js
Normal file
30
backend/service-privateroom/models/Message.js
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
const mongoose = require("mongoose")
|
||||||
|
const config = require("../config");
|
||||||
|
|
||||||
|
const url = config.mongodbHost+config.mongodbDatabase;
|
||||||
|
|
||||||
|
mongoose.connect(url,({useNewUrlParser: true, useUnifiedTopology: true})).then( function(){
|
||||||
|
console.log('mongodb-privated-room connected '+mongoose.connection.readyState);
|
||||||
|
}).catch(function(err){
|
||||||
|
console.log('error : '+err);
|
||||||
|
});
|
||||||
|
|
||||||
|
const MessageSchema = new mongoose.Schema(
|
||||||
|
{
|
||||||
|
conversationId: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
sender: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
date:{
|
||||||
|
type: Date,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ timestamps: true, versionKey: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports = mongoose.model(config.mongodbPrivatedMessages, MessageSchema);
|
||||||
25
backend/service-privateroom/package.json
Normal file
25
backend/service-privateroom/package.json
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"name": "service-privateroom",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "server.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"body-parser": "^1.19.0",
|
||||||
|
"cookie-parser": "^1.4.5",
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"express": "^4.17.1",
|
||||||
|
"fs": "0.0.1-security",
|
||||||
|
"jsonwebtoken": "^8.5.1",
|
||||||
|
"mongoose": "^5.12.11",
|
||||||
|
"socket.io": "^4.1.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"request": "^2.88.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
174
backend/service-privateroom/routes/conversations.js
Normal file
174
backend/service-privateroom/routes/conversations.js
Normal file
|
|
@ -0,0 +1,174 @@
|
||||||
|
const router = require("express").Router();
|
||||||
|
const Conversation = require("../models/Conversation");
|
||||||
|
const {sendError, sendMessage} = require ("../message");
|
||||||
|
|
||||||
|
// new conv
|
||||||
|
router.post("/newConv", async (req, res) => {
|
||||||
|
if (typeof req.body.sender === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ sender');
|
||||||
|
if (typeof req.body.receiver === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ receiver');
|
||||||
|
const newConversation = new Conversation({
|
||||||
|
members: [req.body.sender, req.body.receiver], owner: null
|
||||||
|
});
|
||||||
|
|
||||||
|
try{
|
||||||
|
const savedConversation = await newConversation.save();
|
||||||
|
sendMessage(res,savedConversation._id);
|
||||||
|
}catch (err){
|
||||||
|
sendError(res,err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// get conv
|
||||||
|
router.post("/getConv", async (req, res) => {
|
||||||
|
if (typeof req.body.sender === 'undefined' && typeof req.body.member === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ sender ou member');
|
||||||
|
if (typeof req.body.receiver === 'undefined' && typeof req.body.roomName === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ receiver ou roomName');
|
||||||
|
|
||||||
|
if (typeof req.body.sender === 'undefined'){
|
||||||
|
try {
|
||||||
|
const conversation = await Conversation.find({members: {$in: [req.body.member]}, roomName: req.body.roomName},{_id:1});
|
||||||
|
if(conversation === []){
|
||||||
|
sendError(res, 'Not found');
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
sendMessage(res,conversation[0]);
|
||||||
|
}
|
||||||
|
}catch (err){
|
||||||
|
sendError(res,err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
try {
|
||||||
|
const conversation = await Conversation.findOne({$or: [{members: {$eq: [req.body.sender,req.body.receiver]}},{members: {$eq: [req.body.receiver,req.body.sender]}}]},{_id:1});
|
||||||
|
console.log(conversation);
|
||||||
|
sendMessage(res,conversation);
|
||||||
|
}catch (err){
|
||||||
|
sendError(res,err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// getRooms
|
||||||
|
router.post("/getRooms", async (req, res) => {
|
||||||
|
if (typeof req.body.member === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ member');
|
||||||
|
try {
|
||||||
|
const conversation = await Conversation.find({members: {$in: [req.body.member]}, roomName: {$exists: true}},{});
|
||||||
|
console.log(conversation);
|
||||||
|
sendMessage(res,conversation);
|
||||||
|
}catch (err){
|
||||||
|
sendError(res,err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// getMembers
|
||||||
|
router.post("/getMembers", async (req, res) => {
|
||||||
|
if (typeof req.body.conversationid === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ conversationid');
|
||||||
|
try {
|
||||||
|
const conversation = await Conversation.find({_id: req.body.conversationid},{members: 1});
|
||||||
|
sendMessage(res,conversation);
|
||||||
|
}catch (err){
|
||||||
|
sendError(res,err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// new Room
|
||||||
|
router.post("/newRoom", async (req, res) => {
|
||||||
|
if (typeof req.body.owner === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ owner');
|
||||||
|
if (typeof req.body.roomName === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ roomName');
|
||||||
|
await Conversation.updateOne(
|
||||||
|
{roomName: req.body.roomName},
|
||||||
|
{$setOnInsert: {members: req.body.owner, owner: req.body.owner, roomName: req.body.roomName}},
|
||||||
|
{upsert:true},function(err,result){
|
||||||
|
if(result !== undefined){
|
||||||
|
if(typeof result.upserted !== 'undefined'){
|
||||||
|
sendMessage(res,result.upserted[0]._id);
|
||||||
|
}else{
|
||||||
|
sendError(res,'Room already exist');
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
sendError(res,err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// add Room Member
|
||||||
|
router.post("/addRoomMember", async (req, res) => {
|
||||||
|
if (typeof req.body.conversationid === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ conversationId');
|
||||||
|
if (typeof req.body.owner === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ owner');
|
||||||
|
if (typeof req.body.member === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ member');
|
||||||
|
if(req.body.member === req.body.owner){
|
||||||
|
return sendError(res, 'Impossible de vous ajouter vous même');
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
await Conversation.updateOne(
|
||||||
|
{_id: req.body.conversationid, owner: req.body.owner},
|
||||||
|
{$addToSet: {members: req.body.member}},
|
||||||
|
{useFindAndModify: false},
|
||||||
|
function(err, result){
|
||||||
|
if(result !== undefined){
|
||||||
|
console.log(result);
|
||||||
|
if(result.nModified === 1){
|
||||||
|
sendMessage(res,req.body.member+' added');
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
sendError(res,'Seul le propriétaire de la room peut ajouter des membres.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
sendError(res,err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}catch (err){
|
||||||
|
sendError(res,err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// remove Room Member
|
||||||
|
router.post("/removeRoomMember", async (req, res) => {
|
||||||
|
if (typeof req.body.conversationid === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ conversationId');
|
||||||
|
if (typeof req.body.owner === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ owner');
|
||||||
|
if (typeof req.body.member === 'undefined')
|
||||||
|
return sendError(res, 'Vous n\'avez pas envoyé le champ member');
|
||||||
|
if(req.body.member === req.body.owner){
|
||||||
|
return sendError(res, 'Impossible de vous enlever vous même');
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
await Conversation.updateOne(
|
||||||
|
{_id: req.body.conversationid, owner: req.body.owner},
|
||||||
|
{$pull: {members: req.body.member}},
|
||||||
|
{useFindAndModify: false},
|
||||||
|
function(err, result){
|
||||||
|
if(result !== undefined){
|
||||||
|
console.log(result);
|
||||||
|
if(result.nModified === 1){
|
||||||
|
sendMessage(res,req.body.member+' removed');
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
sendError(res,'Seul le propriétaire de la room peut retirer des membres.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
sendError(res,err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}catch (err){
|
||||||
|
sendError(res,err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
|
|
||||||
143
backend/service-privateroom/server.js
Normal file
143
backend/service-privateroom/server.js
Normal file
|
|
@ -0,0 +1,143 @@
|
||||||
|
const express = require('express');
|
||||||
|
const app = express();
|
||||||
|
const port = process.env.PORT || 3002;
|
||||||
|
const http = require('http');
|
||||||
|
const { Server } = require("socket.io");
|
||||||
|
const server = http.createServer(app);
|
||||||
|
const io = new Server(server, {
|
||||||
|
cors: {
|
||||||
|
origin: "http://localhost:4200",
|
||||||
|
methods: ["GET", "POST"],
|
||||||
|
credentials: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const bodyParser = require('body-parser');
|
||||||
|
app.use(bodyParser.urlencoded({extended:true}));
|
||||||
|
app.use(bodyParser.json());
|
||||||
|
|
||||||
|
const cookieParser = require('cookie-parser');
|
||||||
|
app.use(cookieParser());
|
||||||
|
|
||||||
|
const cors = require('cors');
|
||||||
|
app.use(cors({origin: 'http://localhost:4200', credentials: true}));
|
||||||
|
|
||||||
|
const auth = require("./auth");
|
||||||
|
|
||||||
|
const Message = require("./models/Message");
|
||||||
|
const conversationRoute = require("./routes/conversations");
|
||||||
|
app.use("/conversations", conversationRoute);
|
||||||
|
|
||||||
|
const Conversation = require("./models/Conversation");
|
||||||
|
Conversation.updateOne(
|
||||||
|
{roomName: 'Demonstration Room'},
|
||||||
|
{$setOnInsert: {members: ['cloud','yuki','wilfried','khai'], owner: 'cloud', roomName: 'Demonstration Room'}},
|
||||||
|
{upsert:true},function(err,result){
|
||||||
|
if(result !== undefined){
|
||||||
|
if(typeof result.upserted !== 'undefined'){
|
||||||
|
Message.insertMany([
|
||||||
|
{
|
||||||
|
conversationId: result.upserted[0]._id,
|
||||||
|
sender: 'yuki',
|
||||||
|
text: 'Message à des fins de démonstration pour private room de Yûki',
|
||||||
|
date: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: result.upserted[0]._id,
|
||||||
|
sender: 'wilfried',
|
||||||
|
text: 'Message à des fins de démonstration pour private room de Wilfried',
|
||||||
|
date: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: result.upserted[0]._id,
|
||||||
|
sender: 'khai',
|
||||||
|
text: 'Message à des fins de démonstration pour private room de Khai',
|
||||||
|
date: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conversationId: result.upserted[0]._id,
|
||||||
|
sender: 'cloud',
|
||||||
|
text: 'Message à des fins de démonstration pour private room de Cloud',
|
||||||
|
date: new Date()
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}else{
|
||||||
|
console.log('Room already exist');
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
io.on('connection',socket => {
|
||||||
|
|
||||||
|
auth.getSession(socket.request, function(res){
|
||||||
|
const getUsername = auth.getUsername(res);
|
||||||
|
if (getUsername === -1) {
|
||||||
|
console.log('not authenticated',getUsername);
|
||||||
|
socket.send('error','not authenticated');
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
socket.on('joinroom', function (data){
|
||||||
|
console.log(`${new Date()}] ${getUsername} joined the chat.`);
|
||||||
|
const conversationId = data.room;
|
||||||
|
socket.broadcast.emit(conversationId,[{
|
||||||
|
username: 'Server',
|
||||||
|
date: new Date(),
|
||||||
|
channel: conversationId,
|
||||||
|
message: `${getUsername} joined the chat.`
|
||||||
|
}]);
|
||||||
|
|
||||||
|
Message.find({conversationId: {$eq: conversationId}}, {'_id':0, 'username': '$sender', 'date':'$date', 'channel':'$conversationId', 'message':'$text'},{sort: {'date':1}},(err, res) => {
|
||||||
|
if(err) throw err;
|
||||||
|
if(res.length > 0){
|
||||||
|
socket.emit(conversationId,res);
|
||||||
|
}
|
||||||
|
socket.emit(conversationId,[{
|
||||||
|
username: 'Server',
|
||||||
|
date: new Date(),
|
||||||
|
channel: conversationId,
|
||||||
|
message: `${getUsername} joined the chat.`
|
||||||
|
}]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('privateroom',function(data){
|
||||||
|
console.log(`${getUsername} joined the chat.`);
|
||||||
|
const sender = data.sender;
|
||||||
|
const conversationId = data.room;
|
||||||
|
const date = data.date;
|
||||||
|
const message = data.message;
|
||||||
|
|
||||||
|
Message.insertMany([{
|
||||||
|
conversationId: conversationId,
|
||||||
|
sender: sender,
|
||||||
|
text: message,
|
||||||
|
date: date
|
||||||
|
}
|
||||||
|
]).then(function(){
|
||||||
|
console.log(data, "inserted");
|
||||||
|
const newData = {
|
||||||
|
username: data.sender,
|
||||||
|
date: data.date,
|
||||||
|
channel: conversationId,
|
||||||
|
message: data.message
|
||||||
|
}
|
||||||
|
socket.broadcast.emit(conversationId,[newData]);
|
||||||
|
socket.emit(conversationId,[newData]);
|
||||||
|
}).catch(function(error){
|
||||||
|
console.log("error",error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("disconnect", function() {
|
||||||
|
console.log(`${new Date()}] ${getUsername} left the chat.`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
server.listen(port, '0.0.0.0',() => {
|
||||||
|
console.log (`listening on port ${port}`);
|
||||||
|
});
|
||||||
|
|
@ -13,9 +13,11 @@ services:
|
||||||
depends_on:
|
depends_on:
|
||||||
- service-authentication
|
- service-authentication
|
||||||
- service-message
|
- service-message
|
||||||
|
- service-privateroom
|
||||||
links:
|
links:
|
||||||
- service-authentication
|
- service-authentication
|
||||||
- service-message
|
- service-message
|
||||||
|
- service-privateroom
|
||||||
|
|
||||||
service-authentication:
|
service-authentication:
|
||||||
container_name: service-authentication
|
container_name: service-authentication
|
||||||
|
|
@ -32,7 +34,7 @@ services:
|
||||||
links:
|
links:
|
||||||
- mongodb-authentication
|
- mongodb-authentication
|
||||||
environment:
|
environment:
|
||||||
NODE_ENV: development
|
NODE_ENV: production
|
||||||
|
|
||||||
service-message:
|
service-message:
|
||||||
container_name: service-message
|
container_name: service-message
|
||||||
|
|
@ -42,13 +44,31 @@ services:
|
||||||
- backend/service-message
|
- backend/service-message
|
||||||
- backend/service-message/node_modules
|
- backend/service-message/node_modules
|
||||||
ports:
|
ports:
|
||||||
- 3001:3000
|
- 3001:3001
|
||||||
depends_on:
|
depends_on:
|
||||||
- mongodb-message
|
- mongodb-message
|
||||||
links:
|
links:
|
||||||
- mongodb-message
|
- mongodb-message
|
||||||
|
- service-authentication
|
||||||
environment:
|
environment:
|
||||||
NODE_ENV: development
|
NODE_ENV: production
|
||||||
|
|
||||||
|
service-privateroom:
|
||||||
|
container_name: service-privateroom
|
||||||
|
build: ./backend/service-privateroom
|
||||||
|
command: node server.js
|
||||||
|
volumes:
|
||||||
|
- backend/service-privateroom
|
||||||
|
- backend/service-privateroom/node_modules
|
||||||
|
ports:
|
||||||
|
- 3002:3002
|
||||||
|
depends_on:
|
||||||
|
- mongodb-privateroom
|
||||||
|
links:
|
||||||
|
- mongodb-privateroom
|
||||||
|
- service-authentication
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
|
||||||
mongodb-authentication:
|
mongodb-authentication:
|
||||||
image: mongo
|
image: mongo
|
||||||
|
|
@ -65,3 +85,11 @@ services:
|
||||||
- ./backend/service-message/database:/data/db-message
|
- ./backend/service-message/database:/data/db-message
|
||||||
ports:
|
ports:
|
||||||
- 27020:27017
|
- 27020:27017
|
||||||
|
|
||||||
|
mongodb-privateroom:
|
||||||
|
image: mongo
|
||||||
|
container_name: mongodb-privateroom
|
||||||
|
volumes:
|
||||||
|
- ./backend/service-privateroom/database:/data/db-privateroom
|
||||||
|
ports:
|
||||||
|
- 27021:27017
|
||||||
|
|
@ -34,18 +34,23 @@
|
||||||
"src/assets"
|
"src/assets"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
|
"node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
|
||||||
"node_modules/bootstrap/scss/bootstrap.scss",
|
"node_modules/bootstrap/scss/bootstrap.scss",
|
||||||
"src/styles.scss"
|
"src/styles.scss"
|
||||||
],
|
],
|
||||||
"scripts": []
|
"scripts": [
|
||||||
|
"node_modules/jquery/dist/jquery.min.js",
|
||||||
|
"node_modules/popper.js/dist/umd/popper.min.js",
|
||||||
|
"node_modules/bootstrap/dist/js/bootstrap.min.js"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"production": {
|
"production": {
|
||||||
"budgets": [
|
"budgets": [
|
||||||
{
|
{
|
||||||
"type": "initial",
|
"type": "initial",
|
||||||
"maximumWarning": "500kb",
|
"maximumWarning": "1mb",
|
||||||
"maximumError": "1mb"
|
"maximumError": "2mb"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "anyComponentStyle",
|
"type": "anyComponentStyle",
|
||||||
|
|
|
||||||
4075
frontend/package-lock.json
generated
4075
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -23,8 +23,13 @@
|
||||||
"@angular/router": "~12.0.1",
|
"@angular/router": "~12.0.1",
|
||||||
"@ng-bootstrap/ng-bootstrap": "^8.0.0",
|
"@ng-bootstrap/ng-bootstrap": "^8.0.0",
|
||||||
"@types/socket.io-client": "^3.0.0",
|
"@types/socket.io-client": "^3.0.0",
|
||||||
|
"angular-bootstrap-md": "^11.1.0",
|
||||||
"bootstrap": "^4.6.0",
|
"bootstrap": "^4.6.0",
|
||||||
"jquery": "^3.6.0",
|
"jquery": "^3.6.0",
|
||||||
|
"jquery.js": "0.0.2-security",
|
||||||
|
"jquery.min.js": "^3.5.1",
|
||||||
|
"popper": "^1.0.1",
|
||||||
|
"popper.js": "^1.16.1",
|
||||||
"rxjs": "^7.1.0",
|
"rxjs": "^7.1.0",
|
||||||
"socket.io-client": "^4.1.2",
|
"socket.io-client": "^4.1.2",
|
||||||
"tslib": "^2.1.0",
|
"tslib": "^2.1.0",
|
||||||
|
|
@ -35,6 +40,7 @@
|
||||||
"@angular/cli": "~12.0.1",
|
"@angular/cli": "~12.0.1",
|
||||||
"@angular/compiler-cli": "~12.0.1",
|
"@angular/compiler-cli": "~12.0.1",
|
||||||
"@types/jasmine": "~3.6.0",
|
"@types/jasmine": "~3.6.0",
|
||||||
|
"@types/jquery": "^3.5.5",
|
||||||
"@types/node": "^12.11.1",
|
"@types/node": "^12.11.1",
|
||||||
"jasmine-core": "~3.7.0",
|
"jasmine-core": "~3.7.0",
|
||||||
"karma": "~6.3.0",
|
"karma": "~6.3.0",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<h1 mat-dialog-title>Ajouter un membre</h1>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
<br>
|
||||||
|
<div mat-dialog-content>
|
||||||
|
<p>Saisissez un nouveau nom d'utilisateur à ajouter à la room</p>
|
||||||
|
<input matInput [(ngModel)]="memberName" class="w-100">
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="alert alert-danger w-100" *ngIf="errorMessage!==''"><span class="font-weight-bold">Erreur : </span>{{errorMessage}}</div>
|
||||||
|
<div mat-dialog-actions class="float-right">
|
||||||
|
<button mat-raised-button color="accent" class="mb-2" (click)="onNoClick()">Fermer</button>
|
||||||
|
<button mat-raised-button color="primary" class="mb-2" (click)="onAddMember()" cdkFocusInitial>Ajouter le membre</button>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AddMemberDialogComponent } from './add-member-dialog.component';
|
||||||
|
|
||||||
|
describe('AddMemberDialogComponent', () => {
|
||||||
|
let component: AddMemberDialogComponent;
|
||||||
|
let fixture: ComponentFixture<AddMemberDialogComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ AddMemberDialogComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(AddMemberDialogComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
import {Component, Inject, OnInit} from '@angular/core';
|
||||||
|
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
||||||
|
import {MessageService} from "../services/message/message.service";
|
||||||
|
import {environment} from "../../environments/environment";
|
||||||
|
|
||||||
|
export interface AddMemberDialogData {
|
||||||
|
owner: string;
|
||||||
|
conversationid: string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-add-member-dialog',
|
||||||
|
templateUrl: './add-member-dialog.component.html',
|
||||||
|
styleUrls: ['./add-member-dialog.component.scss']
|
||||||
|
})
|
||||||
|
export class AddMemberDialogComponent{
|
||||||
|
|
||||||
|
memberName = '';
|
||||||
|
errorMessage = '';
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<AddMemberDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: AddMemberDialogData,
|
||||||
|
@Inject(MessageService) private messageService: MessageService) { }
|
||||||
|
|
||||||
|
onNoClick(): void {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
onAddMember(){
|
||||||
|
this.messageService.sendMessage(environment.urlCPR, "conversations/addRoomMember", {owner: this.data.owner, conversationid: this.data.conversationid, member: this.memberName}).subscribe(data => {
|
||||||
|
if (data.status !== 'ok') {
|
||||||
|
console.log(data.data.reason);
|
||||||
|
this.errorMessage = data.data.reason;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
this.dialogRef.close({
|
||||||
|
data: data.data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,21 +1,36 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
import {LoginComponent} from "./login/login.component";
|
import {LoginComponent} from "./login/login.component";
|
||||||
import {GeneralComponent} from "./general/general.component";
|
import {ChatComponent} from "./chat/chat.component";
|
||||||
|
import {AuthGuard} from "./auth.guard";
|
||||||
|
import {ChangePasswordComponent} from "./change-password/change-password.component";
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
|
// {
|
||||||
|
// path: 'login',
|
||||||
|
// component: LoginComponent,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: '',
|
||||||
|
// canActivateChild: [AuthGuard],
|
||||||
|
// children: [
|
||||||
|
// { path: 'chat', component: ChatComponent},
|
||||||
|
// { path: 'changePassword', component: ChangePasswordComponent}
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
{
|
{
|
||||||
path: 'login',
|
path: '',
|
||||||
component: LoginComponent,
|
component: LoginComponent,
|
||||||
},
|
},
|
||||||
{
|
{ path: 'chat',
|
||||||
path: 'general',
|
canActivateChild: [AuthGuard],
|
||||||
component: GeneralComponent,
|
component: ChatComponent
|
||||||
}
|
},
|
||||||
|
{ path: 'changePassword', component: ChangePasswordComponent}
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [RouterModule.forRoot(routes)],
|
imports: [RouterModule.forRoot(routes)],
|
||||||
exports: [RouterModule]
|
exports: [RouterModule],
|
||||||
})
|
})
|
||||||
export class AppRoutingModule { }
|
export class AppRoutingModule { }
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
|
<app-navbar></app-navbar>
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,22 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import {Title} from '@angular/platform-browser';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrls: ['./app.component.scss']
|
styleUrls: ['./app.component.scss']
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent implements OnInit{
|
||||||
title = 'frontend';
|
|
||||||
|
constructor(private titleService: Title, private router: Router) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.setTitle('Chat Polytech');
|
||||||
|
}
|
||||||
|
|
||||||
|
public setTitle(newTitle: string): void {
|
||||||
|
this.titleService.setTitle(newTitle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,23 +5,60 @@ import {FormsModule, ReactiveFormsModule} from "@angular/forms";
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { LoginComponent } from './login/login.component';
|
import { LoginComponent } from './login/login.component';
|
||||||
import { GeneralComponent } from './general/general.component';
|
|
||||||
import {CommonModule, DatePipe} from "@angular/common";
|
import {CommonModule, DatePipe} from "@angular/common";
|
||||||
|
import { PrivateComponent } from './private/private.component';
|
||||||
|
import { ChatComponent } from './chat/chat.component';
|
||||||
|
import { MessageComponent } from './message/message.component';
|
||||||
|
import { RegisterComponent } from './register/register.component';
|
||||||
|
import { ChangePasswordComponent } from './change-password/change-password.component';
|
||||||
|
import { NavbarComponent } from './navbar/navbar.component';
|
||||||
|
import {NavbarModule, WavesModule, ButtonsModule, IconsModule} from 'angular-bootstrap-md';
|
||||||
|
import { AddMemberDialogComponent } from './add-member-dialog/add-member-dialog.component';
|
||||||
|
import { RemoveMemberDialogComponent } from './remove-member-dialog/remove-member-dialog.component';
|
||||||
|
import {MatDividerModule} from "@angular/material/divider";
|
||||||
|
import {MatFormFieldModule} from "@angular/material/form-field";
|
||||||
|
import {MatDialogModule} from "@angular/material/dialog";
|
||||||
|
import {MatButtonModule} from "@angular/material/button";
|
||||||
|
import {MatSortModule} from "@angular/material/sort";
|
||||||
|
import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
|
||||||
|
import {CreateRoomDialogComponent} from "./create-room-dialog/create-room-dialog.component";
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
LoginComponent,
|
LoginComponent,
|
||||||
GeneralComponent
|
PrivateComponent,
|
||||||
|
ChatComponent,
|
||||||
|
MessageComponent,
|
||||||
|
RegisterComponent,
|
||||||
|
ChangePasswordComponent,
|
||||||
|
NavbarComponent,
|
||||||
|
CreateRoomDialogComponent,
|
||||||
|
AddMemberDialogComponent,
|
||||||
|
RemoveMemberDialogComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
AppRoutingModule,
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
CommonModule,
|
CommonModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
|
NavbarModule,
|
||||||
|
WavesModule,
|
||||||
|
ButtonsModule,
|
||||||
|
IconsModule,
|
||||||
|
BrowserModule,
|
||||||
|
AppRoutingModule,
|
||||||
|
FormsModule,
|
||||||
|
HttpClientModule,
|
||||||
|
BrowserAnimationsModule,
|
||||||
|
MatSortModule,
|
||||||
|
MatButtonModule,
|
||||||
|
MatDialogModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatDividerModule
|
||||||
],
|
],
|
||||||
providers: [DatePipe],
|
providers: [DatePipe],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
|
|
|
||||||
16
frontend/src/app/auth.guard.spec.ts
Normal file
16
frontend/src/app/auth.guard.spec.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AuthGuard } from './auth.guard';
|
||||||
|
|
||||||
|
describe('AuthGuard', () => {
|
||||||
|
let guard: AuthGuard;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
guard = TestBed.inject(AuthGuard);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(guard).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
24
frontend/src/app/auth.guard.ts
Normal file
24
frontend/src/app/auth.guard.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import {ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, CanActivateChild, Router} from '@angular/router';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import {AuthService} from './services/auth/auth.service';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class AuthGuard implements CanActivateChild {
|
||||||
|
|
||||||
|
constructor(private authService: AuthService, private router: Router) {
|
||||||
|
}
|
||||||
|
|
||||||
|
canActivateChild(
|
||||||
|
childRoute: ActivatedRouteSnapshot,
|
||||||
|
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
|
||||||
|
if(!this.authService.getLogged()){
|
||||||
|
this.router.navigate(['login']);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
<div class="container">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">Changer de mot de passe :</h4>
|
||||||
|
</div>
|
||||||
|
<form>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<div class="form-group mb-0">
|
||||||
|
<input class="form-control" type="password" required="" [(ngModel)]="oldPassword" autocomplete="password-change" id="oldpassword-change" name="oldpassword-name-change" placeholder="old password">
|
||||||
|
<input class="form-control" type="password" required="" [(ngModel)]="newPassword" autocomplete="password2-change" id="newpassword-change" name="newpassword-name-change" placeholder="new password">
|
||||||
|
<input class="form-control" type="password" required="" [(ngModel)]="confirmPassword" autocomplete="password2-change" id="confirmpassword-change" name="confirmpassword-name-change" placeholder="confirm password">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<input class="btn btn-sm btn-primary" name="button-register" (click)="changePassword()" type="submit" value="Changer">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<br>
|
||||||
|
<div class="alert alert-danger" *ngIf="errorMessage!==''">{{errorMessage}}</div>
|
||||||
|
<div class="alert-success" *ngIf="succesMessage!==''">{{succesMessage}}</div>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ChangePasswordComponent } from './change-password.component';
|
||||||
|
|
||||||
|
describe('ChangePasswordComponent', () => {
|
||||||
|
let component: ChangePasswordComponent;
|
||||||
|
let fixture: ComponentFixture<ChangePasswordComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ ChangePasswordComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ChangePasswordComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import {MessageService} from "../services/message/message.service";
|
||||||
|
import {environment} from "../../environments/environment";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-change-password',
|
||||||
|
templateUrl: './change-password.component.html',
|
||||||
|
styleUrls: ['./change-password.component.scss']
|
||||||
|
})
|
||||||
|
export class ChangePasswordComponent implements OnInit {
|
||||||
|
|
||||||
|
username = sessionStorage.getItem('login');
|
||||||
|
oldPassword = '';
|
||||||
|
newPassword = '';
|
||||||
|
confirmPassword = '';
|
||||||
|
errorMessage = '';
|
||||||
|
succesMessage = '';
|
||||||
|
|
||||||
|
constructor(private messageService: MessageService) { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
changePassword(): void {
|
||||||
|
console.log(this.username);
|
||||||
|
if(this.newPassword !== this.confirmPassword){
|
||||||
|
this.errorMessage = 'Les mots de passe ne sont pas identiques.';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.messageService.sendMessage(environment.urlCL,"changePassword",{username: this.username, password: this.oldPassword, newpassword: this.confirmPassword}).subscribe(data => {
|
||||||
|
if (data.status !== 'ok') {
|
||||||
|
this.succesMessage = '';
|
||||||
|
this.errorMessage = data.data.reason;
|
||||||
|
} else {
|
||||||
|
this.errorMessage = '';
|
||||||
|
this.succesMessage = data.data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1
frontend/src/app/chat/chat.component.html
Normal file
1
frontend/src/app/chat/chat.component.html
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<app-private></app-private>
|
||||||
0
frontend/src/app/chat/chat.component.scss
Normal file
0
frontend/src/app/chat/chat.component.scss
Normal file
|
|
@ -1,20 +1,20 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { GeneralComponent } from './general.component';
|
import { ChatComponent } from './chat.component';
|
||||||
|
|
||||||
describe('GeneralComponent', () => {
|
describe('ChatComponent', () => {
|
||||||
let component: GeneralComponent;
|
let component: ChatComponent;
|
||||||
let fixture: ComponentFixture<GeneralComponent>;
|
let fixture: ComponentFixture<ChatComponent>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [ GeneralComponent ]
|
declarations: [ ChatComponent ]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(GeneralComponent);
|
fixture = TestBed.createComponent(ChatComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
15
frontend/src/app/chat/chat.component.ts
Normal file
15
frontend/src/app/chat/chat.component.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-chat',
|
||||||
|
templateUrl: './chat.component.html',
|
||||||
|
styleUrls: ['./chat.component.scss']
|
||||||
|
})
|
||||||
|
export class ChatComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<h1 mat-dialog-title>New room</h1>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
<br>
|
||||||
|
<div mat-dialog-content>
|
||||||
|
<p>Saisissez un nouveau nom de room</p>
|
||||||
|
<input matInput [(ngModel)]="newRoomName" class="w-100">
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="alert alert-danger w-100" *ngIf="errorMessage!==''"><span class="font-weight-bold">Erreur : </span>{{errorMessage}}</div>
|
||||||
|
<div mat-dialog-actions class="float-right">
|
||||||
|
<button mat-raised-button color="accent" class="mb-2" (click)="onNoClick()">Fermer</button>
|
||||||
|
<button mat-raised-button color="primary" class="mb-2" (click)="onCreateRoom()" cdkFocusInitial>Créer la room</button>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CreateRoomDialogComponent } from './create-room-dialog.component';
|
||||||
|
|
||||||
|
describe('CreateRoomDialogComponent', () => {
|
||||||
|
let component: CreateRoomDialogComponent;
|
||||||
|
let fixture: ComponentFixture<CreateRoomDialogComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ CreateRoomDialogComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CreateRoomDialogComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
import {Component, Inject, OnInit} from '@angular/core';
|
||||||
|
import {MessageService} from "../services/message/message.service";
|
||||||
|
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
||||||
|
import {environment} from "../../environments/environment";
|
||||||
|
|
||||||
|
export interface CreateRoomDialogData {
|
||||||
|
owner: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-create-room-dialog',
|
||||||
|
templateUrl: './create-room-dialog.component.html',
|
||||||
|
styleUrls: ['./create-room-dialog.component.scss']
|
||||||
|
})
|
||||||
|
export class CreateRoomDialogComponent{
|
||||||
|
|
||||||
|
newRoomName = '';
|
||||||
|
errorMessage = '';
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<CreateRoomDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: CreateRoomDialogData,
|
||||||
|
@Inject(MessageService) private messageService: MessageService) { }
|
||||||
|
|
||||||
|
onNoClick(): void {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
onCreateRoom(){
|
||||||
|
this.messageService.sendMessage(environment.urlCPR, "conversations/newRoom", {owner: this.data.owner, roomName: this.newRoomName}).subscribe(data => {
|
||||||
|
if (data.status !== 'ok') {
|
||||||
|
console.log(data.data.reason);
|
||||||
|
this.errorMessage = data.data.reason;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
this.dialogRef.close({
|
||||||
|
data: data.data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
<!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; }
|
|
||||||
|
|
||||||
#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; }
|
|
||||||
|
|
||||||
#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>
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
|
|
||||||
import {ChatInfo, ChatService} from "../services/chat/chat.service";
|
|
||||||
import {environment} from "../../environments/environment";
|
|
||||||
import {DatePipe} from "@angular/common";
|
|
||||||
import {MessageService} from "../services/message/message.service";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-general',
|
|
||||||
templateUrl: './general.component.html',
|
|
||||||
styleUrls: ['./general.component.scss']
|
|
||||||
})
|
|
||||||
export class GeneralComponent implements OnInit {
|
|
||||||
|
|
||||||
private username = sessionStorage.getItem('login');
|
|
||||||
private room = 'general';
|
|
||||||
public msg = '';
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
@ViewChild('ulMessages') ulMsg: ElementRef;
|
|
||||||
|
|
||||||
|
|
||||||
constructor(private chatservice: ChatService, private pipe: DatePipe, private messageservice: MessageService) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
console.log('General working');
|
|
||||||
this.messageservice.sendMessage(environment.urlCL,'getUsers', {username: this.username}).subscribe(
|
|
||||||
data => {
|
|
||||||
if (data.status !== 'ok'){
|
|
||||||
console.log(data.data.reason);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
console.log(data.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
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>');
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,27 +2,22 @@
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h4 class="modal-title">Veuillez-vous authentifier :</h4>
|
<h4 class="modal-title">Veuillez-vous authentifier :</h4>
|
||||||
</div>
|
</div>
|
||||||
|
<form>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<div class="form-group mb-0">
|
<div class="form-group mb-0">
|
||||||
<input type="text"
|
<input class="form-control" type="text" required="" [(ngModel)]="login" autocomplete="login" id="login" name="login" placeholder="login">
|
||||||
placeholder="Entrez votre login"
|
<input class="form-control" type="password" required="" [(ngModel)]="password" autocomplete="password" id="password" name="password" placeholder="password">
|
||||||
class="form-control"
|
</div>
|
||||||
[(ngModel)]="login">
|
|
||||||
<input type="text"
|
|
||||||
placeholder="Entrez votre password"
|
|
||||||
class="form-control"
|
|
||||||
[(ngModel)]="password">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="modal-footer">
|
||||||
|
<input class="btn btn-sm btn-primary" name="button-connexion" (click)="showCredentials()" type="submit" value="Se connecter">
|
||||||
<div class="modal-footer">
|
</div>
|
||||||
<button class="btn btn-sm btn-primary" (click) = "showCredentials()">Connexion Privée</button>
|
</form>
|
||||||
<button class="btn btn-sm btn-primary" (click) = "showCredentials()">Connexion Générale</button>
|
<br>
|
||||||
</div>
|
<div class="alert alert-danger" *ngIf="errorMessage!==''">{{errorMessage}}</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<app-register></app-register>
|
||||||
|
|
|
||||||
|
|
@ -20,16 +20,16 @@ export class LoginComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
showCredentials(): void {
|
showCredentials(): void {
|
||||||
console.log('Login :', this.login);
|
// console.log('Login :', this.login);
|
||||||
console.log('Password :', this.password);
|
// console.log('Password :', this.password);
|
||||||
this.auth.sendAuthentication(this.login, this.password).subscribe(data => {
|
this.auth.sendAuthentication(this.login, this.password).subscribe(data => {
|
||||||
this.auth.finalizeAuthentication(data);
|
this.auth.finalizeAuthentication(data);
|
||||||
if (this.auth.islog === true) {
|
if (this.auth.getLogged()) {
|
||||||
sessionStorage.setItem('login', this.login);
|
sessionStorage.setItem('login', this.login);
|
||||||
this.router.navigateByUrl('/general');
|
this.router.navigateByUrl('/chat');
|
||||||
} else {
|
} else {
|
||||||
this.errorMessage = data.data.reason;
|
this.errorMessage = data.data.reason;
|
||||||
console.log(this.errorMessage);
|
//console.log(this.errorMessage);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
28
frontend/src/app/message/message.component.html
Normal file
28
frontend/src/app/message/message.component.html
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<div class="chat-container">
|
||||||
|
<div class="chat-header bg-primary">
|
||||||
|
<p class="username" *ngIf="room !== 'general'">{{room}}</p>
|
||||||
|
<p class="username" *ngIf="room === 'general'">General</p>
|
||||||
|
<p class="username" *ngIf="room === ''">PLEASE CHOOSE A ROOM</p>
|
||||||
|
<div class="pull-right">
|
||||||
|
<input *ngIf="room !== '' && room !== 'general' && typeRoom === true" class="btn btn-sm btn-primary" name="button-change-private" (click)="addMember()" type="submit" value="+">
|
||||||
|
<input *ngIf="room !== '' && room !== 'general' && typeRoom === true" class="btn btn-sm btn-primary" name="button-change-private" (click)="removeMember()" type="submit" value="-">
|
||||||
|
<input *ngIf="room !== '' && room !== 'general' && typeRoom === true" class="btn btn-sm btn-primary" name="button-change-private" (click)="listMembers()" type="submit" value="Members">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div #scrollContainer class="chat-body" >
|
||||||
|
<ul #ulMessages id="messages">
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="chat-footer">
|
||||||
|
<div class="row col-xl-12 col-lg-12 col-md-12 col-sm-12 col-12">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<div class="form-group mb-0">
|
||||||
|
<input type="text" placeholder="Entrez votre message" (keydown.enter)="sendButtonClick()" class="form-control" [(ngModel)]="msg"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 text-center align-self-center">
|
||||||
|
<button class="btn btn-primary btn-bm px-3" (click)="sendButtonClick()" id="button-send">Envoyer</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
6
frontend/src/app/message/message.component.scss
Normal file
6
frontend/src/app/message/message.component.scss
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#messages { list-style-type: none; margin: 0; padding: 0; }
|
||||||
|
#messages > li { padding: 0.5rem 1rem; }
|
||||||
|
#messages > li:nth-child(odd) { background: #007bff; }
|
||||||
|
.chat-container .chat-header {
|
||||||
|
height: 60px;
|
||||||
|
}
|
||||||
25
frontend/src/app/message/message.component.spec.ts
Normal file
25
frontend/src/app/message/message.component.spec.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { MessageComponent } from './message.component';
|
||||||
|
|
||||||
|
describe('MessageComponent', () => {
|
||||||
|
let component: MessageComponent;
|
||||||
|
let fixture: ComponentFixture<MessageComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ MessageComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(MessageComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
224
frontend/src/app/message/message.component.ts
Normal file
224
frontend/src/app/message/message.component.ts
Normal file
|
|
@ -0,0 +1,224 @@
|
||||||
|
import {Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core';
|
||||||
|
import {ChatInfo, ChatService} from "../services/chat/chat.service";
|
||||||
|
import {DatePipe} from "@angular/common";
|
||||||
|
import {environment} from "../../environments/environment";
|
||||||
|
import {MessageService} from "../services/message/message.service";
|
||||||
|
import {MatDialog} from "@angular/material/dialog";
|
||||||
|
import {AddMemberDialogComponent} from "../add-member-dialog/add-member-dialog.component";
|
||||||
|
import {RemoveMemberDialogComponent} from "../remove-member-dialog/remove-member-dialog.component";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-message',
|
||||||
|
templateUrl: './message.component.html',
|
||||||
|
styleUrls: ['./message.component.scss']
|
||||||
|
})
|
||||||
|
export class MessageComponent implements OnInit, OnChanges {
|
||||||
|
|
||||||
|
public username = sessionStorage.getItem('login');
|
||||||
|
public msg = '';
|
||||||
|
public roomId = '';
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
@Input() room: string;
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
@Input() typeRoom: boolean;
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
@ViewChild('ulMessages') ulMsg: ElementRef;
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
@ViewChild('scrollContainer') scrollContainer: ElementRef;
|
||||||
|
|
||||||
|
constructor(private chatservice: ChatService, private pipe: DatePipe, private messageservice: MessageService, public dialog: MatDialog) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges){
|
||||||
|
//console.log('ngOnChange :'+this.room);
|
||||||
|
this.chatservice.leaveRoom();
|
||||||
|
// @ts-ignore
|
||||||
|
document.getElementById('messages').innerHTML = '';
|
||||||
|
if(this.room === 'General' || this.room === 'general'){
|
||||||
|
this.room = 'general';
|
||||||
|
this.chatservice.setUrl(environment.urlCG);
|
||||||
|
this.chatservice.setRoom(this.room);
|
||||||
|
this.chatServiceOnNewMessage(this.room);
|
||||||
|
}
|
||||||
|
else if(this.room !== ''){
|
||||||
|
let dataMessage;
|
||||||
|
if(this.typeRoom){
|
||||||
|
dataMessage = {
|
||||||
|
member: this.username,
|
||||||
|
roomName: this.room,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
dataMessage = {
|
||||||
|
sender: this.username,
|
||||||
|
receiver: this.room,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.chatservice.setUrl(environment.urlCPR);
|
||||||
|
this.messageservice.sendMessage(environment.urlCPR,"conversations/getConv",dataMessage).subscribe(data => {
|
||||||
|
if (data.status !== 'ok') {
|
||||||
|
console.log(data.data.reason);
|
||||||
|
} else {
|
||||||
|
if(data.data === null){
|
||||||
|
this.messageservice.sendMessage(environment.urlCPR, "conversations/newConv", {
|
||||||
|
sender: this.username,
|
||||||
|
receiver: this.room,
|
||||||
|
}).subscribe(data2 => {
|
||||||
|
if (data2.status !== 'ok') {
|
||||||
|
console.log(data2.data.reason);
|
||||||
|
} else {
|
||||||
|
//console.log(data.data);
|
||||||
|
this.roomId = data2.data._id;
|
||||||
|
this.chatservice.setRoom(this.roomId)
|
||||||
|
this.chatServiceOnNewMessage(this.roomId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if(typeof data.data !== 'undefined' && typeof data.data._id !== 'undefined'){
|
||||||
|
//console.log(data.data);
|
||||||
|
this.roomId = data.data._id;
|
||||||
|
this.chatservice.setRoom(this.roomId);
|
||||||
|
this.chatServiceOnNewMessage(this.roomId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chatServiceOnNewMessage(room: string){
|
||||||
|
this.chatservice.onNewMessage(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-primary">['+this.pipe.transform(data.date, 'dd/MM/yyyy HH:MM:ss')+'] </span><span class="text-danger">'+data.message+'</span></li>');
|
||||||
|
}
|
||||||
|
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>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sendButtonClick(){
|
||||||
|
//console.log('Button working');
|
||||||
|
if(this.msg && this.username && this.room){
|
||||||
|
if(this.room === 'general'){
|
||||||
|
//console.log("sendButton general");
|
||||||
|
this.chatservice.sendMessage(this.username, this.room, this.msg);
|
||||||
|
//console.log(this.username, this.room, this.msg);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
//console.log("sendButton private");
|
||||||
|
this.chatservice.sendMessage(this.username, this.roomId, this.msg);
|
||||||
|
//console.log(this.username, this.roomId, this.msg);
|
||||||
|
}
|
||||||
|
this.msg = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addMember(){
|
||||||
|
let dataMessage;
|
||||||
|
if(this.typeRoom){
|
||||||
|
dataMessage = {
|
||||||
|
member: this.username,
|
||||||
|
roomName: this.room,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
dataMessage = {
|
||||||
|
sender: this.username,
|
||||||
|
receiver: this.room,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.messageservice.sendMessage(environment.urlCPR, "conversations/getConv", dataMessage).subscribe(data => {
|
||||||
|
if (data.status !== 'ok') {
|
||||||
|
console.log(data.data.reason);
|
||||||
|
} else {
|
||||||
|
this.roomId = data.data._id;
|
||||||
|
const dialogRef = this.dialog.open(AddMemberDialogComponent, {
|
||||||
|
width: '50%',
|
||||||
|
data: {owner: this.username, conversationid: this.roomId}
|
||||||
|
});
|
||||||
|
dialogRef.afterClosed().subscribe(data2 => {
|
||||||
|
console.log(data2);
|
||||||
|
this.listMembers();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
removeMember(){
|
||||||
|
let dataMessage;
|
||||||
|
if(this.typeRoom){
|
||||||
|
dataMessage = {
|
||||||
|
member: this.username,
|
||||||
|
roomName: this.room,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
dataMessage = {
|
||||||
|
sender: this.username,
|
||||||
|
receiver: this.room,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.messageservice.sendMessage(environment.urlCPR, "conversations/getConv", dataMessage).subscribe(data => {
|
||||||
|
if (data.status !== 'ok') {
|
||||||
|
console.log(data.data.reason);
|
||||||
|
} else {
|
||||||
|
this.roomId = data.data._id;
|
||||||
|
const dialogRef = this.dialog.open(RemoveMemberDialogComponent, {
|
||||||
|
width: '50%',
|
||||||
|
data: {owner: this.username, conversationid: this.roomId}
|
||||||
|
});
|
||||||
|
dialogRef.afterClosed().subscribe(data2 => {
|
||||||
|
console.log(data2);
|
||||||
|
this.listMembers();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
listMembers(){
|
||||||
|
let dataMessage;
|
||||||
|
if(this.typeRoom){
|
||||||
|
dataMessage = {
|
||||||
|
member: this.username,
|
||||||
|
roomName: this.room,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
dataMessage = {
|
||||||
|
sender: this.username,
|
||||||
|
receiver: this.room,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.messageservice.sendMessage(environment.urlCPR, "conversations/getConv", dataMessage).subscribe(data => {
|
||||||
|
if (data.status !== 'ok') {
|
||||||
|
console.log(data.data.reason);
|
||||||
|
} else {
|
||||||
|
this.roomId = data.data._id;
|
||||||
|
this.messageservice.sendMessage(environment.urlCPR, "conversations/getMembers", {conversationid: this.roomId}).subscribe(data2 => {
|
||||||
|
if (data2.status !== 'ok') {
|
||||||
|
console.log(data2.data.reason);
|
||||||
|
} else {
|
||||||
|
if(typeof data2.data[0] !== 'undefined'){
|
||||||
|
this.ulMsg.nativeElement.insertAdjacentHTML('beforeend', '<li><span class="text-danger">Membres: '+data2.data[0].members+'</span></li>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
15
frontend/src/app/navbar/navbar.component.html
Normal file
15
frontend/src/app/navbar/navbar.component.html
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-light bg-primary">
|
||||||
|
<a class="navbar-brand" href="/chat">Chat Polytech</a>
|
||||||
|
|
||||||
|
<ul class="navbar-nav ml-auto" *ngIf="true;">
|
||||||
|
<!-- Dropdown -->
|
||||||
|
<li class="nav-item dropdown" dropdown>
|
||||||
|
<a role="button" data-toggle="dropdown" type="button" class="nav-link dropdown-toggle ">Profile</a>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right dropdown dropdown-primary" role="menu">
|
||||||
|
<a class="dropdown-item waves-light" href="changePassword">Change password</a>
|
||||||
|
<!-- <div class="divider dropdown-divider"></div>-->
|
||||||
|
<a class="dropdown-item waves-light" href="#" (click)="logout()">Log out</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
0
frontend/src/app/navbar/navbar.component.scss
Normal file
0
frontend/src/app/navbar/navbar.component.scss
Normal file
25
frontend/src/app/navbar/navbar.component.spec.ts
Normal file
25
frontend/src/app/navbar/navbar.component.spec.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
});
|
||||||
24
frontend/src/app/navbar/navbar.component.ts
Normal file
24
frontend/src/app/navbar/navbar.component.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import {AuthService} from "../services/auth/auth.service";
|
||||||
|
import {Router} from "@angular/router";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-navbar',
|
||||||
|
templateUrl: './navbar.component.html',
|
||||||
|
styleUrls: ['./navbar.component.scss']
|
||||||
|
})
|
||||||
|
export class NavbarComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor(public authservice: AuthService, private router: Router) { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
logout(){
|
||||||
|
//console.log('connecté ? '+this.authservice.getLogged());
|
||||||
|
console.log('test');
|
||||||
|
this.authservice.setLogged(false);
|
||||||
|
this.router.navigate(['/']);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
24
frontend/src/app/private/private.component.html
Normal file
24
frontend/src/app/private/private.component.html
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<div class="container col-xl-12 col-lg-12 col-md-12 col-sm-12 col-12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xl-4 col-lg-4 col-md-4 col-sm-3 col-3">
|
||||||
|
<br>
|
||||||
|
<div class="btn-group">
|
||||||
|
<input *ngIf="privateRoomActivate === false" class="btn btn-sm btn-primary" name="button-change-private" (click)="changeListPrivate()" type="submit" value="Private Room">
|
||||||
|
<input *ngIf="privateRoomActivate === false" class="btn btn-sm btn-primary" name="button-change-private" (click)="changeListGeneral()" type="submit" value="Actualiser">
|
||||||
|
<input *ngIf="privateRoomActivate === true" class="btn btn-sm btn-primary" name="button-change-private" (click)="changeListGeneral()" type="submit" value="Home Room">
|
||||||
|
<input *ngIf="privateRoomActivate === true" class="btn btn-sm btn-primary" name="button-change-private" (click)="newRoom()" type="submit" value="New Room">
|
||||||
|
<input *ngIf="privateRoomActivate === true" class="btn btn-sm btn-primary" name="button-change-private" (click)="changeListPrivate()" type="submit" value="Actualiser">
|
||||||
|
</div>
|
||||||
|
<div #userList class="user-list-card" id="userList" (click)="selectRoom($event)">
|
||||||
|
<div class="user-card">
|
||||||
|
<img src="../../assets/image/general.png" height="25" width="25" />
|
||||||
|
<p class="username">General</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xl-8 col-lg-8 col-md-8 col-sm-9 col-9">
|
||||||
|
<br>
|
||||||
|
<app-message [room]="roomSelected" [typeRoom]="privateRoomActivate"></app-message>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
9
frontend/src/app/private/private.component.scss
Normal file
9
frontend/src/app/private/private.component.scss
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
.btn-group{
|
||||||
|
height: 60px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
.user-list-card{
|
||||||
|
height: calc(100% - 80px);
|
||||||
|
}
|
||||||
25
frontend/src/app/private/private.component.spec.ts
Normal file
25
frontend/src/app/private/private.component.spec.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
});
|
||||||
91
frontend/src/app/private/private.component.ts
Normal file
91
frontend/src/app/private/private.component.ts
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
|
||||||
|
import {environment} from "../../environments/environment";
|
||||||
|
import {ChatService} from "../services/chat/chat.service";
|
||||||
|
import {MessageService} from "../services/message/message.service";
|
||||||
|
import {CreateRoomDialogComponent} from "../create-room-dialog/create-room-dialog.component";
|
||||||
|
import {MatDialog} from "@angular/material/dialog";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-private',
|
||||||
|
templateUrl: './private.component.html',
|
||||||
|
styleUrls: ['./private.component.scss']
|
||||||
|
})
|
||||||
|
export class PrivateComponent implements OnInit {
|
||||||
|
|
||||||
|
public username = sessionStorage.getItem('login');
|
||||||
|
public roomSelected = 'general';
|
||||||
|
public privateRoomActivate = false;
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
@ViewChild('userList') userList: ElementRef;
|
||||||
|
|
||||||
|
constructor(private chatservice: ChatService, private messageservice: MessageService, public dialog: MatDialog) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.changeListGeneral();
|
||||||
|
}
|
||||||
|
|
||||||
|
selectRoom(event: Event): void {
|
||||||
|
if((event.target as Element).className !== 'user-list-card'){
|
||||||
|
const room = (event.target as Element).textContent;
|
||||||
|
//console.log(room);
|
||||||
|
if(room !== '' && room !== null) {
|
||||||
|
this.roomSelected = room;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changeListPrivate(): void{
|
||||||
|
this.roomSelected = '';
|
||||||
|
this.privateRoomActivate = true;
|
||||||
|
// @ts-ignore
|
||||||
|
document.getElementById('userList').innerHTML = '';
|
||||||
|
this.messageservice.sendMessage(environment.urlCPR,'conversations/getRooms', {member: this.username}).subscribe(
|
||||||
|
data => {
|
||||||
|
if (data.status !== 'ok'){
|
||||||
|
console.log(data.data.reason);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
console.log(data.data);
|
||||||
|
for(let user of data.data){
|
||||||
|
if(user !== undefined && user.roomName !== undefined){
|
||||||
|
this.userList.nativeElement.insertAdjacentHTML('beforeend', '<div class="user-card" [id]="'+user.roomName+'"><img src="../../assets/image/room.png" height="25" width="25"/><p class="username">'+user.roomName+'</p></div>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
changeListGeneral(): void{
|
||||||
|
this.roomSelected = 'general';
|
||||||
|
this.privateRoomActivate = false;
|
||||||
|
// @ts-ignore
|
||||||
|
document.getElementById('userList').innerHTML = '<div class="user-card"><img src="../../assets/image/general.png" height="25" width="25"/><p class="username">General</p></div>';
|
||||||
|
this.messageservice.sendMessage(environment.urlCL,'getUsers', {username: this.username}).subscribe(
|
||||||
|
data => {
|
||||||
|
if (data.status !== 'ok'){
|
||||||
|
console.log(data.data.reason);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
for(let user of data.data){
|
||||||
|
if(user !== undefined && user.login !== undefined){
|
||||||
|
this.userList.nativeElement.insertAdjacentHTML('beforeend', '<div class="user-card" [id]="'+user.login+'"><img src="../../assets/image/user.png" height="25" width="25"/><p class="username">'+user.login+'</p></div>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
newRoom(): void{
|
||||||
|
const dialogRef = this.dialog.open(CreateRoomDialogComponent, {
|
||||||
|
width: '50%',
|
||||||
|
data: {owner: this.username}
|
||||||
|
});
|
||||||
|
dialogRef.afterClosed().subscribe(data => {
|
||||||
|
console.log(data);
|
||||||
|
this.changeListPrivate();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
24
frontend/src/app/register/register.component.html
Normal file
24
frontend/src/app/register/register.component.html
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<div class="container">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">Vous pouvez aussi vous enregistrer ici</h4>
|
||||||
|
</div>
|
||||||
|
<form>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<div class="form-group mb-0">
|
||||||
|
<input class="form-control" type="text" required="" [(ngModel)]="login2" autocomplete="login-register" id="login-register" name="login-name-register" placeholder="login">
|
||||||
|
<input class="form-control" type="password" required="" [(ngModel)]="password2" autocomplete="password-register" id="password-register" name="password-name-register" placeholder="password">
|
||||||
|
<input class="form-control" type="password" required="" [(ngModel)]="password4" autocomplete="password2-register" id="password2-register" name="password2-name-register" placeholder="confirmation password">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<input class="btn btn-sm btn-primary" name="button-register" (click)="register()" type="submit" value="S'enregistrer">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<br>
|
||||||
|
<div class="alert alert-danger" *ngIf="errorMessage!==''">{{errorMessage}}</div>
|
||||||
|
<div class="alert-success" *ngIf="succesMessage!==''">{{succesMessage}}</div>
|
||||||
|
</div>
|
||||||
0
frontend/src/app/register/register.component.scss
Normal file
0
frontend/src/app/register/register.component.scss
Normal file
25
frontend/src/app/register/register.component.spec.ts
Normal file
25
frontend/src/app/register/register.component.spec.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { RegisterComponent } from './register.component';
|
||||||
|
|
||||||
|
describe('RegisterComponent', () => {
|
||||||
|
let component: RegisterComponent;
|
||||||
|
let fixture: ComponentFixture<RegisterComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ RegisterComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(RegisterComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
42
frontend/src/app/register/register.component.ts
Normal file
42
frontend/src/app/register/register.component.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import {MessageService} from "../services/message/message.service";
|
||||||
|
import {environment} from "../../environments/environment";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-register',
|
||||||
|
templateUrl: './register.component.html',
|
||||||
|
styleUrls: ['./register.component.scss']
|
||||||
|
})
|
||||||
|
export class RegisterComponent implements OnInit {
|
||||||
|
|
||||||
|
login2 = '';
|
||||||
|
password2 = '';
|
||||||
|
password4 = '';
|
||||||
|
errorMessage = '';
|
||||||
|
succesMessage = '';
|
||||||
|
|
||||||
|
constructor(private messageService: MessageService) { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
register(): void {
|
||||||
|
if(this.password4 !== this.password2){
|
||||||
|
console.log("error");
|
||||||
|
this.errorMessage = 'Les mots de passe ne sont pas identiques.';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.messageService.sendMessage(environment.urlCL,"register",{username: this.login2, password: this.password2}).subscribe(data => {
|
||||||
|
if (data.status !== 'ok') {
|
||||||
|
this.succesMessage = '';
|
||||||
|
this.errorMessage = data.data.reason;
|
||||||
|
} else {
|
||||||
|
//console.log(data.data);
|
||||||
|
this.errorMessage = '';
|
||||||
|
this.succesMessage = data.data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<h1 mat-dialog-title>Retirer un membre</h1>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
<br>
|
||||||
|
<div mat-dialog-content>
|
||||||
|
<p>Saisissez un nouveau nom d'utilisateur à retirer à la room</p>
|
||||||
|
<input matInput [(ngModel)]="memberName" class="w-100">
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="alert alert-danger w-100" *ngIf="errorMessage!==''"><span class="font-weight-bold">Erreur : </span>{{errorMessage}}</div>
|
||||||
|
<div mat-dialog-actions class="float-right">
|
||||||
|
<button mat-raised-button color="accent" class="mb-2" (click)="onNoClick()">Fermer</button>
|
||||||
|
<button mat-raised-button color="primary" class="mb-2" (click)="onDeleteMember()" cdkFocusInitial>Retirer le membre</button>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { RemoveMemberDialogComponent } from './remove-member-dialog.component';
|
||||||
|
|
||||||
|
describe('RemoveMemberDialogComponent', () => {
|
||||||
|
let component: RemoveMemberDialogComponent;
|
||||||
|
let fixture: ComponentFixture<RemoveMemberDialogComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ RemoveMemberDialogComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(RemoveMemberDialogComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
import {Component, Inject, OnInit} from '@angular/core';
|
||||||
|
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
||||||
|
import {MessageService} from "../services/message/message.service";
|
||||||
|
import {environment} from "../../environments/environment";
|
||||||
|
import {AddMemberDialogData} from "../add-member-dialog/add-member-dialog.component";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-remove-member-dialog',
|
||||||
|
templateUrl: './remove-member-dialog.component.html',
|
||||||
|
styleUrls: ['./remove-member-dialog.component.scss']
|
||||||
|
})
|
||||||
|
export class RemoveMemberDialogComponent {
|
||||||
|
|
||||||
|
memberName = '';
|
||||||
|
errorMessage = '';
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<RemoveMemberDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: AddMemberDialogData,
|
||||||
|
@Inject(MessageService) private messageService: MessageService) { }
|
||||||
|
|
||||||
|
onNoClick(): void {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
onDeleteMember(){
|
||||||
|
this.messageService.sendMessage(environment.urlCPR, "conversations/removeRoomMember", {owner: this.data.owner, conversationid: this.data.conversationid, member: this.memberName}).subscribe(data => {
|
||||||
|
if (data.status !== 'ok') {
|
||||||
|
console.log(data.data.reason);
|
||||||
|
this.errorMessage = data.data.reason;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
this.dialogRef.close({
|
||||||
|
data: data.data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -10,9 +10,10 @@ import {environment} from "../../../environments/environment";
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
islog: boolean;
|
private islog: boolean;
|
||||||
|
|
||||||
constructor(private messageService: MessageService) { }
|
constructor(private messageService: MessageService) {
|
||||||
|
}
|
||||||
|
|
||||||
getLogged(): boolean {
|
getLogged(): boolean {
|
||||||
return this.islog;
|
return this.islog;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ export interface ChatInfo {
|
||||||
message: string
|
message: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
|
|
@ -31,6 +30,7 @@ export class ChatService {
|
||||||
|
|
||||||
setRoom(room: string){
|
setRoom(room: string){
|
||||||
this.room = room;
|
this.room = room;
|
||||||
|
this.joinRoom(this.room);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSocket(){
|
setSocket(){
|
||||||
|
|
@ -39,17 +39,42 @@ export class ChatService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessage(username: string | null, room: string, message: string) {
|
sendMessage(sender: string | null, room: string, message: string) {
|
||||||
// @ts-ignore
|
if(room === 'general' || room === 'General'){
|
||||||
this.socket.emit(room, {
|
// @ts-ignore
|
||||||
username: username,
|
this.socket.emit(room, {
|
||||||
date: new Date(),
|
username: sender,
|
||||||
room: room,
|
date: new Date(),
|
||||||
message: message
|
room: room,
|
||||||
|
message: message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
//console.log('sendMessage private: ',sender,room,message);
|
||||||
|
// @ts-ignore
|
||||||
|
this.socket.emit('privateroom', {
|
||||||
|
sender: sender,
|
||||||
|
room: room,
|
||||||
|
date: new Date(),
|
||||||
|
message: message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
joinRoom(room: string): void{
|
||||||
|
//@ts-ignore
|
||||||
|
this.socket.emit('joinroom', {
|
||||||
|
room: room
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leaveRoom(): void {
|
||||||
|
// @ts-ignore
|
||||||
|
this.socket?.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
onNewMessage(room: string): Observable<ChatInfo[]> {
|
onNewMessage(room: string): Observable<ChatInfo[]> {
|
||||||
|
//console.log('onNewMessage: ',room);
|
||||||
return new Observable(observer => {
|
return new Observable(observer => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.socket.on(room, (data: ChatInfo[]) => {
|
this.socket.on(room, (data: ChatInfo[]) => {
|
||||||
|
|
|
||||||
BIN
frontend/src/assets/image/general.png
Normal file
BIN
frontend/src/assets/image/general.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 166 KiB |
BIN
frontend/src/assets/image/room.png
Normal file
BIN
frontend/src/assets/image/room.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
|
|
@ -1,3 +1,6 @@
|
||||||
export const environment = {
|
export const environment = {
|
||||||
production: true
|
production: true,
|
||||||
|
urlCL: 'http://localhost:3000',
|
||||||
|
urlCG: 'http://localhost:3001',
|
||||||
|
urlCPR: 'http://localhost:3002'
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,9 @@
|
||||||
|
|
||||||
export const environment = {
|
export const environment = {
|
||||||
production: false,
|
production: false,
|
||||||
urlCL: 'http://127.0.0.1:3000',
|
urlCL: 'http://localhost:3000',
|
||||||
urlCG: 'http://127.0.0.1:3001'
|
urlCG: 'http://localhost:3001',
|
||||||
|
urlCPR: 'http://localhost:3002'
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.container-fluid {
|
.container-fluid {
|
||||||
padding: 50px 200px;
|
padding-left: 5vh;
|
||||||
|
padding-right: 5vh;
|
||||||
|
padding-top: 1vh;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -12,7 +14,8 @@ body {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05);
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05);
|
||||||
height: calc(100vh - 100px);
|
height: calc(100vh - 100px);
|
||||||
padding: 10px;
|
padding: 0;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
.user-card {
|
.user-card {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -28,6 +31,7 @@ body {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
margin-left: 5px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
@ -48,46 +52,29 @@ body {
|
||||||
|
|
||||||
.chat-header {
|
.chat-header {
|
||||||
height: 70px;
|
height: 70px;
|
||||||
background-color: #E5E5E5;
|
background-color: steelblue;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.username {
|
.username {
|
||||||
font-size: 14px;
|
font-size: 20px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
margin-left: 5px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-body {
|
.chat-body {
|
||||||
background-image: url(./assets/image/user.png);
|
background-color: white;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position: center center;
|
background-position: center center;
|
||||||
height: calc(100vh - 125px);
|
height: 76vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
.message-container {
|
|
||||||
background-color: white;
|
|
||||||
padding: 7px;
|
|
||||||
border-radius: 5px;
|
|
||||||
width: fit-content;
|
|
||||||
max-width: 90%;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.same-user {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
|
|
||||||
.message-container {
|
|
||||||
background-color: lightskyblue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-footer {
|
.chat-footer {
|
||||||
|
|
@ -97,13 +84,14 @@ body {
|
||||||
right: 0;
|
right: 0;
|
||||||
background-color: #EDEDED;
|
background-color: #EDEDED;
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
|
width: auto;
|
||||||
|
|
||||||
.form-control {
|
#button {
|
||||||
background-color: white;
|
size: auto;
|
||||||
border: 1px solid #D8DDEC;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: 1rem;
|
|
||||||
color: black;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-footer{
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
|
||||||
Reference in a new issue