Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
c51f984267
23 changed files with 1473 additions and 72 deletions
|
|
@ -1,8 +1,6 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
FROM node:current-slim
|
||||
ENV NODE_ENV=production
|
||||
WORKDIR /app-authentication
|
||||
COPY ["package.json", "package-lock.json*", "./"]
|
||||
RUN npm install --production
|
||||
RUN npm install
|
||||
COPY . .
|
||||
CMD [ "node", "server.js" ]
|
||||
44
backend/service-authentication/auth.js
Normal file
44
backend/service-authentication/auth.js
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
const sessionJwt = require ('./sessionJWT');
|
||||
const queries = require('./mongodbQueries');
|
||||
|
||||
// ici, on récupère le contenu du cookie de session JWT.
|
||||
// celui-ci contient le userId mais également des informations
|
||||
// concernant sa date d'expiration.
|
||||
function getSession (req) {
|
||||
return sessionJwt.decodeSessionCookie(req);
|
||||
}
|
||||
module.exports.getSession = getSession;
|
||||
|
||||
// cette fonction ajoute le cookie de session au headers du
|
||||
// message qui sera renvoyé à Angular. Si le cookie actuel
|
||||
// est "vieux", on en recrée ici un nouveau.
|
||||
function setSessionCookie (req, res, session) {
|
||||
sessionJwt.createSessionCookie(req, res, session);
|
||||
}
|
||||
module.exports.setSessionCookie = setSessionCookie;
|
||||
|
||||
// fonction pour récupérer le userId provenant du cookie
|
||||
// de session. Si ce dernier n'existe pas, on renvoie
|
||||
// l'ID -1.
|
||||
function getUserId(session) {
|
||||
if (typeof session.userId === 'undefined') return -1;
|
||||
return session.userId;
|
||||
}
|
||||
module.exports.getUserId = getUserId;
|
||||
|
||||
async function authenticate(req, res) {
|
||||
const login = req.body.login;
|
||||
const password = req.body.password;
|
||||
|
||||
const userList = await queries.checkLoginQuery(login, password);
|
||||
if (userList !== undefined && userList[0] !== undefined && userList[0].idUtilisateur > 0){
|
||||
console.log("check");
|
||||
setSessionCookie (req, res, { username: login});
|
||||
return userList[0].idUtilisateur;
|
||||
} else {
|
||||
setSessionCookie (req, res, {username: -1});
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
module.exports.authenticate = authenticate;
|
||||
21
backend/service-authentication/checkLogin.js
Normal file
21
backend/service-authentication/checkLogin.js
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
const {sendError, sendMessage} = require ("./message");
|
||||
const auth = require ('./auth');
|
||||
|
||||
async function checkLogin (req,res) {
|
||||
if (typeof req.body.login === 'undefined')
|
||||
return sendError(res, 'Vous n\'avez pas envoyé le champ login');
|
||||
if (typeof req.body.password === 'undefined')
|
||||
return sendError(res, 'Vous n\'avez pas envoyé le champ password');
|
||||
|
||||
const result = await auth.authenticate(req, res);
|
||||
if (result > 0){
|
||||
return sendMessage(res, {
|
||||
id: result,
|
||||
username: req.body.login
|
||||
});
|
||||
}
|
||||
else{
|
||||
return sendError(res, 'Invalid username or password');
|
||||
}
|
||||
}
|
||||
module.exports = checkLogin;
|
||||
15
backend/service-authentication/config.js
Normal file
15
backend/service-authentication/config.js
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
const config = {
|
||||
// paramètres de connexion à la base de données
|
||||
mongodbDatabase: 'chat',
|
||||
mongodbHost: 'mongodb://mongodb-authentication:27017/',
|
||||
charset: 'utf8',
|
||||
mongodbLogin: '',
|
||||
mongodbPassword: '',
|
||||
|
||||
// les noms des tables
|
||||
mongodbUtilisateurs: 'users'
|
||||
};
|
||||
module.exports = config;
|
||||
|
||||
|
||||
|
||||
27
backend/service-authentication/keys/jwtRS256.key
Normal file
27
backend/service-authentication/keys/jwtRS256.key
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEAvtgwBVQ26VNO1XD+PTZDdZJdWXufontRZIO/ev7OkvH8qM6g
|
||||
mZDJOZQRrbaMI2w3jGr/x1uDhIaafRtyRsQ9Jdjb2GVjQc9deiNMfeEvA1YJZjiC
|
||||
LDy4igtmitPup3WrG+xb9asNAuQUtn1bXKM/3ecVxIKq6j/wh1578ra9WGpcTZjx
|
||||
+1u+3LjviWehb9Gwu8FOIPBu9bcIf48JZLr3Zq/0Fv0Atw7gTJBDAb2B9Zsjxc59
|
||||
oKKyWguRQG6COUaxZ/Lsyczv0FIFFsfAKzuihqfI+EsVGJ1nsFBH3gAdeUW2RX7/
|
||||
z+7cmR305sf3cdN7kcK8ZwgrG7/lnszSUf79uQIDAQABAoIBAAKKDdmETVa9bQca
|
||||
Acf+uNcPo35VTsJysZqMxjd0vHroDVyRo0Fn08WYWsPc8fBmuDZ+FfkpFo7k25le
|
||||
jB607btbL1Gpx7BQegXuAk6KeH2q32Uky1abWDk9/ZdLSpmfzy8H7hFOvVWUg1IK
|
||||
SPTqlyb0tC1xL6T+RM0ITM3l8I8ElWHKzhs5H9jLlhOng0sW9RbLjWtBRXPp48tB
|
||||
YFhx/wuSNpTOVGZAKpWVMaCgOizeL0yT6t+z/QL7Pvq3IhlcFMLz5K6f6/mZ+ODV
|
||||
W/TpbwC7ll204vmgHsYY6tdpDAKqZK0ayPxm018QCCtCsYawDyk2HjYYnytXSsNu
|
||||
UNPt+KECgYEA6WkKd5Nh8K0m9LVL3Gpbep9MKTqGgBVo8z4UV6iSDQdCBUSU8cFi
|
||||
2ntsyAh0PCvQHxvn/DwqCcKafbFQMX+S1jpkZsoqA0OUjYRxQYOEn1iIGJdspzYl
|
||||
cv2637p3Aza6x75eFLOZvFa3C1rCFQxJHvAYolN/FnhBx9D3QnaDydsCgYEA0VCJ
|
||||
z4kVFm35poBEAVJOO3fdmFUvAn3bFhgI5zfzC/e4dPs9beiWo9XmpeOapu9D7F3M
|
||||
1OFITUw1yQBoDtG5Gt/cIp39wdPNLfDM3kgv/djQGa/EZO1NkDrk/AGDZqyzDTUV
|
||||
vGB/d8dGQdP9buiZFcy9D3HSsNVD9RP547+mfPsCgYEAywfa2f6yr/b+LthQ368I
|
||||
WdadGjPVcS6udv+mFEYGnRyWGhz47n4IbgH0st9ftENsKtNMbQUskAbd+b22Awh0
|
||||
grKSSTNLbkFnw93T4mfzgeQxpip5kc2wr6Dz387D3WDLAhqenaVIciJ/4HmW31Yr
|
||||
eKTi2LiGkNYUaipkGkUbCAcCgYEAmHvCmWT07s0ZJLmmUQwjn+D3lqTfxUHoW9UQ
|
||||
j1jL/3jscJQisTHSo/IMv+bqYBhH9CZ1NNQVdvJA8HgSVlFkNvbECJfuJ8jjXUdi
|
||||
B8Cw7Y2INF4+hYP2kE7HR+rWTfMb0VBN0FjAI4MRZJ1JsAVUmHP5ewnhgh8rDZwK
|
||||
3GZepAcCgYEA1LwjdqCg3LJzXVSJ6gWwNNB9gRX2bb2l7iMHxaTEyRFvJFW7cuL9
|
||||
Y7iCKw+9EpGqSZesIHk1V+TCj77nXKpsyO+/tmiyyeqa1DT+AvvG+IgB0aJto7kU
|
||||
f2oxn02dX9hN51tRhHZ6PDV/43GnJ3ltaXLBhCxq/MQZFXztYkUd6Z0=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
9
backend/service-authentication/keys/jwtRS256.key.pub
Normal file
9
backend/service-authentication/keys/jwtRS256.key.pub
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvtgwBVQ26VNO1XD+PTZD
|
||||
dZJdWXufontRZIO/ev7OkvH8qM6gmZDJOZQRrbaMI2w3jGr/x1uDhIaafRtyRsQ9
|
||||
Jdjb2GVjQc9deiNMfeEvA1YJZjiCLDy4igtmitPup3WrG+xb9asNAuQUtn1bXKM/
|
||||
3ecVxIKq6j/wh1578ra9WGpcTZjx+1u+3LjviWehb9Gwu8FOIPBu9bcIf48JZLr3
|
||||
Zq/0Fv0Atw7gTJBDAb2B9Zsjxc59oKKyWguRQG6COUaxZ/Lsyczv0FIFFsfAKzui
|
||||
hqfI+EsVGJ1nsFBH3gAdeUW2RX7/z+7cmR305sf3cdN7kcK8ZwgrG7/lnszSUf79
|
||||
uQIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
5
backend/service-authentication/keys/jwtRS256.sh
Normal file
5
backend/service-authentication/keys/jwtRS256.sh
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
ssh-keygen -t rsa -b 4096 -m PEM -f jwtRS256.key
|
||||
# Don't add passphrase
|
||||
openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256.key.pub
|
||||
cat jwtRS256.key
|
||||
cat jwtRS256.key.pub
|
||||
13
backend/service-authentication/message.js
Normal file
13
backend/service-authentication/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 };
|
||||
22
backend/service-authentication/mongodbConnect.js
Normal file
22
backend/service-authentication/mongodbConnect.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
const config = require('./config');
|
||||
const MongoClient = require( 'mongodb' ).MongoClient;
|
||||
const uri = config.mongodbHost;
|
||||
let db;
|
||||
|
||||
module.exports = {
|
||||
connectToServer: function( callback ) {
|
||||
MongoClient.connect( uri, { useNewUrlParser: true, useUnifiedTopology: true }, function( err, client ) {
|
||||
if(err) throw err;
|
||||
console.log('mongodb-authentication-checkConnection'+client===undefined);
|
||||
if (client !== undefined) console.log(client.isConnected());
|
||||
db = client.db(config.mongodbDatabase);
|
||||
|
||||
return callback( err );
|
||||
});
|
||||
},
|
||||
|
||||
getDB: function() {
|
||||
return db;
|
||||
}
|
||||
};
|
||||
|
||||
16
backend/service-authentication/mongodbQueries.js
Normal file
16
backend/service-authentication/mongodbQueries.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
const config = require('./config');
|
||||
const mongoDB = require ('./mongodbConnect').getDB();
|
||||
|
||||
function checkLoginQuery(login, password){
|
||||
// SELECT idUtilisateurs
|
||||
// FROM utilisateurs
|
||||
// WHERE login = ? AND password = ?;
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve(mongoDB.collection(config.mongodbUtilisateurs).find(
|
||||
{login: login, password: password},
|
||||
{projection: {idUtilisateur: 1, _id: 0}}).toArray());
|
||||
});
|
||||
}
|
||||
module.exports.checkLoginQuery = checkLoginQuery;
|
||||
|
||||
|
||||
19
backend/service-authentication/package.json
Normal file
19
backend/service-authentication/package.json
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "service-authentication",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Van Khai PHAN",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"body-parser": "^1.19.0",
|
||||
"cookie-parser": "^1.4.5",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.17.1",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"mongodb": "^3.6.9"
|
||||
}
|
||||
}
|
||||
32
backend/service-authentication/server.js
Normal file
32
backend/service-authentication/server.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
const express = require('express');
|
||||
const app = express();
|
||||
const port = process.env.PORT || 3000;
|
||||
|
||||
const cookieParser = require('cookie-parser');
|
||||
app.use(cookieParser());
|
||||
|
||||
const bodyParser = require('body-parser');
|
||||
app.use(bodyParser.urlencoded({extended:true}));
|
||||
app.use(bodyParser.json());
|
||||
|
||||
const cors = require('cors');
|
||||
app.use(cors({origin: 'http://127.0.0.1:4200', credentials: true}));
|
||||
|
||||
const mongoConnect = require('./mongodbConnect');
|
||||
|
||||
mongoConnect.connectToServer(function( err, client ) {
|
||||
if (err)
|
||||
console.log(err);
|
||||
|
||||
const checkLogin = require('./checkLogin');
|
||||
|
||||
app.post('/checkLogin', (req, res) => {
|
||||
checkLogin(req,res);
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log (`listening on port ${port}`);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
88
backend/service-authentication/sessionJWT.js
Normal file
88
backend/service-authentication/sessionJWT.js
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
const sessionJWT = require ('jsonwebtoken');
|
||||
const fs = require ('fs');
|
||||
|
||||
// renvoie un nouveau token JWT
|
||||
function createSessionJWT (userId) {
|
||||
// ci-dessous, on met en place le cookie de session JWT :
|
||||
// 1/ on recupere notre clef privee
|
||||
const RSA_PRIVATE_KEY = fs.readFileSync('./keys/jwtRS256.key');
|
||||
|
||||
// 2/ on signe un token JWT. Le payload est l'identifiant de
|
||||
// l'utilisateur ainsi qu'une date d'expiration à mi-parcours :
|
||||
// on récupérra ultérieurement ces informations, qui permettront
|
||||
// de savoir si le token est valide ou non et de connaître l'ID
|
||||
// de l'utilisateur. Dans le token, le champ exp indique la date
|
||||
// de validité du token (pas besoin de se relogguer tant que la
|
||||
// date actuelle est inférieure à exp) et le champ midExp indique
|
||||
// à partir de quel moment on doit recréer un nouveau cookie de
|
||||
// session.
|
||||
const jwtToken = sessionJWT.sign(
|
||||
{
|
||||
userId: userId,
|
||||
midExp: Math.floor(Date.now() / 1000) + 1800 // validité: 30mn
|
||||
},
|
||||
RSA_PRIVATE_KEY,
|
||||
{
|
||||
algorithm: 'RS256',
|
||||
expiresIn: '1h' // champ exp: validité 1h
|
||||
});
|
||||
|
||||
return jwtToken;
|
||||
}
|
||||
|
||||
|
||||
// crée un cookie de session JWT (Si le JWT de la requête est encore valide,
|
||||
// on l'utilise, sinon on en recrée un nouveau)
|
||||
function createSessionCookie(req, res, payload) {
|
||||
// on regarde si le payload contient les champs userId et midExp. Si c'est le
|
||||
// cas, c'est qu'on a reçu dans la request un cookie. On va donc vérifier si
|
||||
// ce cookie est encore valide ou non : si la date actuelle est inférieure à
|
||||
// midExp, alors le cookie est encore valide et on peut le renvoyer. Sinon,
|
||||
// on doit recalculer un nouveau cookie.
|
||||
let jwtToken = '';
|
||||
if ((typeof payload.userId !== 'undefined') &&
|
||||
(typeof payload.midExp !== 'undefined') &&
|
||||
(Math.floor(Date.now() / 1000) <= payload.midExp)) {
|
||||
jwtToken = req.cookies.SESSIONID;
|
||||
}
|
||||
else {
|
||||
// on crée un nouveau cookie
|
||||
jwtToken = createSessionJWT(payload.userId);
|
||||
}
|
||||
|
||||
// on renvoie le cookie au client
|
||||
// on met le secure à false afin de pouvoir utiliser http plutôt que https
|
||||
res.cookie('SESSIONID', jwtToken, {httpOnly:true, secure:false});
|
||||
}
|
||||
module.exports.createSessionCookie = createSessionCookie;
|
||||
|
||||
|
||||
// décode un cookie de session et renvoie les informations contenues dans ce
|
||||
// cookie, notamment le userId. Si le cookie n'existe pas, la fonction renvoie
|
||||
// juste un objet avec un userId égal à -1.
|
||||
function decodeSessionCookie(req) {
|
||||
// si l'on n'a pas de cookie de session, on renvoie une session avec vide,
|
||||
// avec juste un userId à -1
|
||||
console.log(req.cookies);
|
||||
if (typeof req.cookies.SESSIONID === 'undefined') {
|
||||
return { userId: -1 };
|
||||
}
|
||||
const sessionid = req.cookies.SESSIONID;
|
||||
|
||||
// on lit la clef publique
|
||||
const RSA_PUBLIC_KEY = fs.readFileSync('./keys/jwtRS256.key.pub');
|
||||
|
||||
// on récupère les données du cookie
|
||||
try {
|
||||
const token = sessionJWT.verify(
|
||||
sessionid,
|
||||
RSA_PUBLIC_KEY,
|
||||
{algorithms: ['RS256']});
|
||||
return token;
|
||||
}
|
||||
catch (err) {
|
||||
return {userId: -1};
|
||||
}
|
||||
}
|
||||
module.exports.decodeSessionCookie = decodeSessionCookie;
|
||||
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
FROM node:current-slim
|
||||
ENV NODE_ENV=production
|
||||
WORKDIR /app-message
|
||||
COPY ["package.json", "package-lock.json*", "./"]
|
||||
RUN npm install --production
|
||||
RUN npm install --NODE_ENV
|
||||
COPY . .
|
||||
CMD [ "node", "server.js" ]
|
||||
26
backend/service-message/auth.js
Normal file
26
backend/service-message/auth.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
const sessionJwt = require ('./sessionJWT');
|
||||
|
||||
// ici, on récupère le contenu du cookie de session JWT.
|
||||
// celui-ci contient le userId mais également des informations
|
||||
// concernant sa date d'expiration.
|
||||
function getSession (req) {
|
||||
return sessionJwt.decodeSessionCookie(req);
|
||||
}
|
||||
module.exports.getSession = getSession;
|
||||
|
||||
// cette fonction ajoute le cookie de session au headers du
|
||||
// message qui sera renvoyé à Angular. Si le cookie actuel
|
||||
// est "vieux", on en recrée ici un nouveau.
|
||||
function setSessionCookie (req, res, session) {
|
||||
sessionJwt.createSessionCookie(req, res, session);
|
||||
}
|
||||
module.exports.setSessionCookie = setSessionCookie;
|
||||
|
||||
// fonction pour récupérer le userId provenant du cookie
|
||||
// de session. Si ce dernier n'existe pas, on renvoie
|
||||
// l'ID -1.
|
||||
function getUsername(session) {
|
||||
if (typeof session.username === 'undefined') return -1;
|
||||
return session.username;
|
||||
}
|
||||
module.exports.getUsername = getUsername;
|
||||
13
backend/service-message/config.js
Normal file
13
backend/service-message/config.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
const config = {
|
||||
mongodbDatabase: 'chat',
|
||||
mongodbHost: 'mongodb://mongodb-message:27020/',
|
||||
charset: 'utf8',
|
||||
mongodbLogin: '',
|
||||
mongodbPassword: '',
|
||||
|
||||
mongodbMessages: 'messages'
|
||||
};
|
||||
module.exports = config;
|
||||
|
||||
|
||||
|
||||
13
backend/service-message/message.js
Normal file
13
backend/service-message/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 };
|
||||
34
backend/service-message/mongodb-message.js
Normal file
34
backend/service-message/mongodb-message.js
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
const config = require('./config');
|
||||
const mongoose = require( 'mongoose' );
|
||||
const url = config.mongodbHost;
|
||||
|
||||
mongoose.connect(url,({useNewUrlParser: true, useUnifiedTopology: true}));
|
||||
console.log(mongoose.connection.readyState);
|
||||
|
||||
const schemaMessage = mongoose.Schema({
|
||||
username:{
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
date:{
|
||||
type: Date,
|
||||
required: true
|
||||
},
|
||||
channel:{
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
message:{
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const messages = mongoose.model(config.mongodbMessages, schemaMessage);
|
||||
|
||||
// messages.find({},(err, messages) => {
|
||||
// if(err) throw err;
|
||||
// console.log(messages);
|
||||
// });
|
||||
|
||||
module.exports = messages;
|
||||
849
backend/service-message/package-lock.json
generated
Normal file
849
backend/service-message/package-lock.json
generated
Normal file
|
|
@ -0,0 +1,849 @@
|
|||
{
|
||||
"name": "service-message",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/bson": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.3.tgz",
|
||||
"integrity": "sha512-mVRvYnTOZJz3ccpxhr3wgxVmSeiYinW+zlzQz3SXWaJmD1DuL05Jeq7nKw3SnbKmbleW5qrLG5vdyWe/A9sXhw==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/component-emitter": {
|
||||
"version": "1.2.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz",
|
||||
"integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg=="
|
||||
},
|
||||
"@types/cookie": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg=="
|
||||
},
|
||||
"@types/cors": {
|
||||
"version": "2.8.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz",
|
||||
"integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ=="
|
||||
},
|
||||
"@types/mongodb": {
|
||||
"version": "3.6.16",
|
||||
"resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.16.tgz",
|
||||
"integrity": "sha512-D3tM0iRUet3TiIMAdvovxAIRG9gYqFd4j7visGwmPNdQj8Fq/uFFfRxyGCgEwVXAs0NnJPMI/QGVTADxDwhmSQ==",
|
||||
"requires": {
|
||||
"@types/bson": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "15.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.6.1.tgz",
|
||||
"integrity": "sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA=="
|
||||
},
|
||||
"accepts": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
|
||||
"requires": {
|
||||
"mime-types": "~2.1.24",
|
||||
"negotiator": "0.6.2"
|
||||
}
|
||||
},
|
||||
"array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||
},
|
||||
"base64-arraybuffer": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
|
||||
"integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI="
|
||||
},
|
||||
"base64id": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
|
||||
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
|
||||
},
|
||||
"bl": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz",
|
||||
"integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==",
|
||||
"requires": {
|
||||
"readable-stream": "^2.3.5",
|
||||
"safe-buffer": "^5.1.1"
|
||||
}
|
||||
},
|
||||
"bluebird": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
|
||||
"integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
|
||||
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
|
||||
"requires": {
|
||||
"bytes": "3.1.0",
|
||||
"content-type": "~1.0.4",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"http-errors": "1.7.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"on-finished": "~2.3.0",
|
||||
"qs": "6.7.0",
|
||||
"raw-body": "2.4.0",
|
||||
"type-is": "~1.6.17"
|
||||
}
|
||||
},
|
||||
"bson": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz",
|
||||
"integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg=="
|
||||
},
|
||||
"buffer-equal-constant-time": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
|
||||
},
|
||||
"bytes": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
|
||||
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
|
||||
},
|
||||
"component-emitter": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
|
||||
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
|
||||
},
|
||||
"content-disposition": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
|
||||
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.2"
|
||||
}
|
||||
},
|
||||
"content-type": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
|
||||
},
|
||||
"cookie-parser": {
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz",
|
||||
"integrity": "sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==",
|
||||
"requires": {
|
||||
"cookie": "0.4.0",
|
||||
"cookie-signature": "1.0.6"
|
||||
}
|
||||
},
|
||||
"cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"cors": {
|
||||
"version": "2.8.5",
|
||||
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||
"requires": {
|
||||
"object-assign": "^4",
|
||||
"vary": "^1"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"denque": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz",
|
||||
"integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ=="
|
||||
},
|
||||
"depd": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
|
||||
},
|
||||
"destroy": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||
},
|
||||
"ecdsa-sig-formatter": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||
},
|
||||
"engine.io": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-5.1.1.tgz",
|
||||
"integrity": "sha512-aMWot7H5aC8L4/T8qMYbLdvKlZOdJTH54FxfdFunTGvhMx1BHkJOntWArsVfgAZVwAO9LC2sryPWRcEeUzCe5w==",
|
||||
"requires": {
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "2.0.0",
|
||||
"cookie": "~0.4.1",
|
||||
"cors": "~2.8.5",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-parser": "~4.0.0",
|
||||
"ws": "~7.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"cookie": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
|
||||
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"engine.io-parser": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz",
|
||||
"integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==",
|
||||
"requires": {
|
||||
"base64-arraybuffer": "0.1.4"
|
||||
}
|
||||
},
|
||||
"escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
|
||||
},
|
||||
"etag": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
|
||||
},
|
||||
"express": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
|
||||
"integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
|
||||
"requires": {
|
||||
"accepts": "~1.3.7",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "1.19.0",
|
||||
"content-disposition": "0.5.3",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "0.4.0",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"finalhandler": "~1.1.2",
|
||||
"fresh": "0.5.2",
|
||||
"merge-descriptors": "1.0.1",
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"proxy-addr": "~2.0.5",
|
||||
"qs": "6.7.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"safe-buffer": "5.1.2",
|
||||
"send": "0.17.1",
|
||||
"serve-static": "1.14.1",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": "~1.5.0",
|
||||
"type-is": "~1.6.18",
|
||||
"utils-merge": "1.0.1",
|
||||
"vary": "~1.1.2"
|
||||
}
|
||||
},
|
||||
"finalhandler": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
||||
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.3",
|
||||
"statuses": "~1.5.0",
|
||||
"unpipe": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"forwarded": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
|
||||
},
|
||||
"fresh": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
||||
},
|
||||
"fs": {
|
||||
"version": "0.0.1-security",
|
||||
"resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
|
||||
"integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ="
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
|
||||
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
|
||||
"requires": {
|
||||
"depd": "~1.1.2",
|
||||
"inherits": "2.0.3",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": ">= 1.5.0 < 2",
|
||||
"toidentifier": "1.0.0"
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"ipaddr.js": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"jsonwebtoken": {
|
||||
"version": "8.5.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
|
||||
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
|
||||
"requires": {
|
||||
"jws": "^3.2.2",
|
||||
"lodash.includes": "^4.3.0",
|
||||
"lodash.isboolean": "^3.0.3",
|
||||
"lodash.isinteger": "^4.0.4",
|
||||
"lodash.isnumber": "^3.0.3",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
"lodash.isstring": "^4.0.1",
|
||||
"lodash.once": "^4.0.0",
|
||||
"ms": "^2.1.1",
|
||||
"semver": "^5.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"jwa": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
|
||||
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
|
||||
"requires": {
|
||||
"buffer-equal-constant-time": "1.0.1",
|
||||
"ecdsa-sig-formatter": "1.0.11",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"jws": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
|
||||
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
|
||||
"requires": {
|
||||
"jwa": "^1.4.1",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"kareem": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.2.tgz",
|
||||
"integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ=="
|
||||
},
|
||||
"lodash.includes": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
|
||||
"integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
|
||||
},
|
||||
"lodash.isboolean": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
|
||||
"integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
|
||||
},
|
||||
"lodash.isinteger": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
|
||||
"integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M="
|
||||
},
|
||||
"lodash.isnumber": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
|
||||
"integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
|
||||
},
|
||||
"lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||
"integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
|
||||
},
|
||||
"lodash.isstring": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
|
||||
"integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
|
||||
},
|
||||
"lodash.once": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
||||
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
|
||||
},
|
||||
"memory-pager": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
|
||||
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
|
||||
"optional": true
|
||||
},
|
||||
"merge-descriptors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||
},
|
||||
"methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.47.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz",
|
||||
"integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.30",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz",
|
||||
"integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==",
|
||||
"requires": {
|
||||
"mime-db": "1.47.0"
|
||||
}
|
||||
},
|
||||
"mongodb": {
|
||||
"version": "3.6.8",
|
||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.8.tgz",
|
||||
"integrity": "sha512-sDjJvI73WjON1vapcbyBD3Ao9/VN3TKYY8/QX9EPbs22KaCSrQ5rXo5ZZd44tWJ3wl3FlnrFZ+KyUtNH6+1ZPQ==",
|
||||
"requires": {
|
||||
"bl": "^2.2.1",
|
||||
"bson": "^1.1.4",
|
||||
"denque": "^1.4.1",
|
||||
"optional-require": "^1.0.3",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"saslprep": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"mongoose": {
|
||||
"version": "5.12.11",
|
||||
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.12.11.tgz",
|
||||
"integrity": "sha512-16TVqYhHQdZNR8RTis/8iiTPy+nJPq0UhKyBFTucLLU3PWcDLY2gAGv6aOk0LygTNhEfgNnENgUUHhjVqTuh8w==",
|
||||
"requires": {
|
||||
"@types/mongodb": "^3.5.27",
|
||||
"bson": "^1.1.4",
|
||||
"kareem": "2.3.2",
|
||||
"mongodb": "3.6.8",
|
||||
"mongoose-legacy-pluralize": "1.0.2",
|
||||
"mpath": "0.8.3",
|
||||
"mquery": "3.2.5",
|
||||
"ms": "2.1.2",
|
||||
"regexp-clone": "1.0.0",
|
||||
"safe-buffer": "5.2.1",
|
||||
"sift": "13.5.2",
|
||||
"sliced": "1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"mongoose-legacy-pluralize": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz",
|
||||
"integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ=="
|
||||
},
|
||||
"mpath": {
|
||||
"version": "0.8.3",
|
||||
"resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.3.tgz",
|
||||
"integrity": "sha512-eb9rRvhDltXVNL6Fxd2zM9D4vKBxjVVQNLNijlj7uoXUy19zNDsIif5zR+pWmPCWNKwAtqyo4JveQm4nfD5+eA=="
|
||||
},
|
||||
"mquery": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.5.tgz",
|
||||
"integrity": "sha512-VjOKHHgU84wij7IUoZzFRU07IAxd5kWJaDmyUzQlbjHjyoeK5TNeeo8ZsFDtTYnSgpW6n/nMNIHvE3u8Lbrf4A==",
|
||||
"requires": {
|
||||
"bluebird": "3.5.1",
|
||||
"debug": "3.1.0",
|
||||
"regexp-clone": "^1.0.0",
|
||||
"safe-buffer": "5.1.2",
|
||||
"sliced": "1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"negotiator": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"on-finished": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
|
||||
"requires": {
|
||||
"ee-first": "1.1.1"
|
||||
}
|
||||
},
|
||||
"optional-require": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz",
|
||||
"integrity": "sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA=="
|
||||
},
|
||||
"parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
|
||||
},
|
||||
"path-to-regexp": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
|
||||
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
|
||||
"requires": {
|
||||
"forwarded": "~0.1.2",
|
||||
"ipaddr.js": "1.9.1"
|
||||
}
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
|
||||
"integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
|
||||
"requires": {
|
||||
"bytes": "3.1.0",
|
||||
"http-errors": "1.7.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"unpipe": "1.0.0"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"regexp-clone": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz",
|
||||
"integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw=="
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"saslprep": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
|
||||
"integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"sparse-bitfield": "^3.0.3"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
},
|
||||
"send": {
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
|
||||
"integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"destroy": "~1.0.4",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "~1.7.2",
|
||||
"mime": "1.6.0",
|
||||
"ms": "2.1.1",
|
||||
"on-finished": "~2.3.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"statuses": "~1.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve-static": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
|
||||
"integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
|
||||
"requires": {
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"parseurl": "~1.3.3",
|
||||
"send": "0.17.1"
|
||||
}
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
|
||||
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
|
||||
},
|
||||
"sift": {
|
||||
"version": "13.5.2",
|
||||
"resolved": "https://registry.npmjs.org/sift/-/sift-13.5.2.tgz",
|
||||
"integrity": "sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA=="
|
||||
},
|
||||
"sliced": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
|
||||
"integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
|
||||
},
|
||||
"socket.io": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.1.2.tgz",
|
||||
"integrity": "sha512-xK0SD1C7hFrh9+bYoYCdVt+ncixkSLKtNLCax5aEy1o3r5PaO5yQhVb97exIe67cE7lAK+EpyMytXWTWmyZY8w==",
|
||||
"requires": {
|
||||
"@types/cookie": "^0.4.0",
|
||||
"@types/cors": "^2.8.8",
|
||||
"@types/node": ">=10.0.0",
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "~2.0.0",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io": "~5.1.0",
|
||||
"socket.io-adapter": "~2.3.0",
|
||||
"socket.io-parser": "~4.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"socket.io-adapter": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.1.tgz",
|
||||
"integrity": "sha512-8cVkRxI8Nt2wadkY6u60Y4rpW3ejA1rxgcK2JuyIhmF+RMNpTy1QRtkHIDUOf3B4HlQwakMsWbKftMv/71VMmw=="
|
||||
},
|
||||
"socket.io-parser": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz",
|
||||
"integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==",
|
||||
"requires": {
|
||||
"@types/component-emitter": "^1.2.10",
|
||||
"component-emitter": "~1.3.0",
|
||||
"debug": "~4.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"sparse-bitfield": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
|
||||
"integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"memory-pager": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"toidentifier": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
|
||||
},
|
||||
"type-is": {
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
||||
"requires": {
|
||||
"media-typer": "0.3.0",
|
||||
"mime-types": "~2.1.24"
|
||||
}
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"utils-merge": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||
},
|
||||
"vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.4.6",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
|
||||
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
22
backend/service-message/package.json
Normal file
22
backend/service-message/package.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "service-message",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
81
backend/service-message/server.js
Normal file
81
backend/service-message/server.js
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
const express = require('express');
|
||||
const http = require('http');
|
||||
const { Server } = require("socket.io");
|
||||
const cors = require ('cors');
|
||||
const cookieParser = require('cookie-parser');
|
||||
const auth = require ('./auth');
|
||||
const bodyParser = require ('body-parser');
|
||||
const {sendError, sendMessage} = require ('./message');
|
||||
const messages = require('./mongodb-message');
|
||||
|
||||
const app = express();
|
||||
const server = http.createServer(app);
|
||||
const io = new Server(server);
|
||||
const port = process.env.PORT || 3000;
|
||||
|
||||
app.use(bodyParser.json());
|
||||
app.use(cors({origin: 'http://127.0.0.1:4200', credentials: true}));
|
||||
app.use(cookieParser());
|
||||
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
const session = auth.getSession(req);
|
||||
const getUsername = auth.getUsername(session);
|
||||
if (getUsername === -1) {
|
||||
//sendError(res, 'not authenticated');
|
||||
}
|
||||
//auth.setSessionCookie(req, res, session);
|
||||
res.sendFile(__dirname + '/index.html');
|
||||
|
||||
});
|
||||
|
||||
io.on('connection',socket => {
|
||||
let users = {}
|
||||
|
||||
socket.on('user', (userData) => {
|
||||
console.log(`${getUsername} joined the chat.`);
|
||||
users[socket.id] = getUsername;
|
||||
messages.find({},(err, res) => {
|
||||
if(err) throw err;
|
||||
if(res.length > 0){
|
||||
const savedChat = res;
|
||||
socket.emit('general',savedChat);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('general',function(data){
|
||||
socket.broadcast.emit('general',data);
|
||||
|
||||
const username = data.username;
|
||||
const date = Date.now();
|
||||
const channel = 'general';
|
||||
const message = data.message;
|
||||
|
||||
messages.insertMany([{
|
||||
username: username,
|
||||
date: date,
|
||||
channel: channel,
|
||||
message: message
|
||||
}
|
||||
]).then(function(){
|
||||
console.log(data, "inserted");
|
||||
}).catch(function(error){
|
||||
console.log("error",error);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
socket.on('typing',(user)=>{
|
||||
socket.broadcast.emit('notifyTyping',user)
|
||||
})
|
||||
|
||||
socket.on("disconnect", function() {
|
||||
console.log(`${socket.id} left the chat.`);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
server.listen(port, () => {
|
||||
console.log('listening on *:3000');
|
||||
});
|
||||
87
backend/service-message/sessionJWT.js
Normal file
87
backend/service-message/sessionJWT.js
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
const sessionJWT = require ('jsonwebtoken');
|
||||
const fs = require ('fs');
|
||||
|
||||
// renvoie un nouveau token JWT
|
||||
function createSessionJWT (userId) {
|
||||
// ci-dessous, on met en place le cookie de session JWT :
|
||||
// 1/ on recupere notre clef privee
|
||||
const RSA_PRIVATE_KEY = fs.readFileSync('./keys/jwtRS256.key');
|
||||
|
||||
// 2/ on signe un token JWT. Le payload est l'identifiant de
|
||||
// l'utilisateur ainsi qu'une date d'expiration à mi-parcours :
|
||||
// on récupérra ultérieurement ces informations, qui permettront
|
||||
// de savoir si le token est valide ou non et de connaître l'ID
|
||||
// de l'utilisateur. Dans le token, le champ exp indique la date
|
||||
// de validité du token (pas besoin de se relogguer tant que la
|
||||
// date actuelle est inférieure à exp) et le champ midExp indique
|
||||
// à partir de quel moment on doit recréer un nouveau cookie de
|
||||
// session.
|
||||
const jwtToken = sessionJWT.sign(
|
||||
{
|
||||
userId: userId,
|
||||
midExp: Math.floor(Date.now() / 1000) + 1800 // validité: 30mn
|
||||
},
|
||||
RSA_PRIVATE_KEY,
|
||||
{
|
||||
algorithm: 'RS256',
|
||||
expiresIn: '1h' // champ exp: validité 1h
|
||||
});
|
||||
|
||||
return jwtToken;
|
||||
}
|
||||
|
||||
|
||||
// crée un cookie de session JWT (Si le JWT de la requête est encore valide,
|
||||
// on l'utilise, sinon on en recrée un nouveau)
|
||||
function createSessionCookie(req, res, payload) {
|
||||
// on regarde si le payload contient les champs userId et midExp. Si c'est le
|
||||
// cas, c'est qu'on a reçu dans la request un cookie. On va donc vérifier si
|
||||
// ce cookie est encore valide ou non : si la date actuelle est inférieure à
|
||||
// midExp, alors le cookie est encore valide et on peut le renvoyer. Sinon,
|
||||
// on doit recalculer un nouveau cookie.
|
||||
let jwtToken = '';
|
||||
if ((typeof payload.userId !== 'undefined') &&
|
||||
(typeof payload.midExp !== 'undefined') &&
|
||||
(Math.floor(Date.now() / 1000) <= payload.midExp)) {
|
||||
jwtToken = req.cookies.SESSIONID;
|
||||
}
|
||||
else {
|
||||
// on crée un nouveau cookie
|
||||
jwtToken = createSessionJWT(payload.userId);
|
||||
}
|
||||
|
||||
// on renvoie le cookie au client
|
||||
// on met le secure à false afin de pouvoir utiliser http plutôt que https
|
||||
res.cookie('SESSIONID', jwtToken, {httpOnly:true, secure:false});
|
||||
}
|
||||
module.exports.createSessionCookie = createSessionCookie;
|
||||
|
||||
|
||||
// décode un cookie de session et renvoie les informations contenues dans ce
|
||||
// cookie, notamment le userId. Si le cookie n'existe pas, la fonction renvoie
|
||||
// juste un objet avec un userId égal à -1.
|
||||
function decodeSessionCookie(req) {
|
||||
// si l'on n'a pas de cookie de session, on renvoie une session avec vide,
|
||||
// avec juste un userId à -1
|
||||
if (typeof req.cookies.SESSIONID === 'undefined') {
|
||||
return { userId: -1 };
|
||||
}
|
||||
const sessionid = req.cookies.SESSIONID;
|
||||
|
||||
// on lit la clef publique
|
||||
const RSA_PUBLIC_KEY = fs.readFileSync('./keys/jwtRS256.key.pub');
|
||||
|
||||
// on récupère les données du cookie
|
||||
try {
|
||||
const token = sessionJWT.verify(
|
||||
sessionid,
|
||||
RSA_PUBLIC_KEY,
|
||||
{algorithms: ['RS256']});
|
||||
return token;
|
||||
}
|
||||
catch (err) {
|
||||
return {userId: -1};
|
||||
}
|
||||
}
|
||||
module.exports.decodeSessionCookie = decodeSessionCookie;
|
||||
|
||||
|
|
@ -1,82 +1,51 @@
|
|||
version: '3.7'
|
||||
networks:
|
||||
net:
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
|
||||
frontend:
|
||||
image: frontend
|
||||
environment:
|
||||
SERVICE_ADRESS: frontend
|
||||
SERVICE_PORT: 4200
|
||||
ports:
|
||||
- 4200:4200
|
||||
networks:
|
||||
- net
|
||||
|
||||
service-authentication:
|
||||
image: service-authentication
|
||||
container_name: service-authentication
|
||||
build: backend/service-authentication
|
||||
command: node server.js
|
||||
volumes:
|
||||
- backend/service-authentication
|
||||
- backend/service-authentication/node_modules
|
||||
ports:
|
||||
- 3000:3000
|
||||
depends_on:
|
||||
- mongodb-authentication
|
||||
links:
|
||||
- mongodb-authentication
|
||||
environment:
|
||||
SERVICE_ADRESS: service-authentication
|
||||
SERVICE_PORT: 3000
|
||||
ports:
|
||||
- 3000:3000
|
||||
networks:
|
||||
- net
|
||||
NODE_ENV: development
|
||||
|
||||
service-message:
|
||||
image: service-message
|
||||
container_name: service-message
|
||||
build: backend/service-message
|
||||
command: node server.js
|
||||
volumes:
|
||||
- backend/service-message
|
||||
- backend/service-message/node_modules
|
||||
ports:
|
||||
- 3001:3000
|
||||
depends_on:
|
||||
- mongodb-message
|
||||
links:
|
||||
- mongodb-message
|
||||
environment:
|
||||
SERVICE_ADRESS: service-message
|
||||
SERVICE_PORT: 3000
|
||||
ports:
|
||||
- 3001:3000
|
||||
networks:
|
||||
- net
|
||||
service-notification:
|
||||
image: service-notification
|
||||
environment:
|
||||
SERVICE_ADRESS: service-notification
|
||||
SERVICE_PORT: 3000
|
||||
ports:
|
||||
- 3002:3000
|
||||
networks:
|
||||
- net
|
||||
|
||||
service-privateroom:
|
||||
image: service-privateroom
|
||||
environment:
|
||||
SERVICE_ADRESS: service-privateroom
|
||||
SERVICE_PORT: 3000
|
||||
ports:
|
||||
- 3003:3000
|
||||
networks:
|
||||
- net
|
||||
NODE_ENV: development
|
||||
|
||||
mongodb-authentication:
|
||||
image: mongo
|
||||
networks:
|
||||
- net
|
||||
container_name: mongodb-authentication
|
||||
volumes:
|
||||
- ./backend/service-authentication/database:/data/db
|
||||
ports:
|
||||
- 27017:27017
|
||||
- 27017:27017
|
||||
|
||||
mongodb-message:
|
||||
image: mongo
|
||||
networks:
|
||||
- net
|
||||
container_name: mongodb-message
|
||||
volumes:
|
||||
- ./backend/service-message/database:/data/db
|
||||
ports:
|
||||
- 27020:27017
|
||||
|
||||
mongodb-notification:
|
||||
image: mongo
|
||||
networks:
|
||||
- net
|
||||
ports:
|
||||
- 27021:27017
|
||||
|
||||
mongodb-privateroom:
|
||||
image: mongo
|
||||
networks:
|
||||
- net
|
||||
ports:
|
||||
- 27022:27017
|
||||
Reference in a new issue