diff --git a/.gitignore b/.gitignore index 140fa633..1cc82b66 100644 --- a/.gitignore +++ b/.gitignore @@ -15,13 +15,11 @@ Thumbs.db *.log # compiled output -/dist node_modules -./srcs/requirement/api_back/node_modules -./srcs/requirement/api_back/dist -./srcs/requirement/api_front/node_modules -./srcs/requirement/api_front/public/build +./srcs/requirement/nestjs/api_back/dist +./srcs/requirements/svelte/api_front/public/build/ + # Logs logs *.log @@ -53,3 +51,7 @@ lerna-debug.log* !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json + +.env + +memo.txt diff --git a/JEU2/make.sh b/JEU2/make.sh deleted file mode 100644 index ebce024a..00000000 --- a/JEU2/make.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -npx tsc - -mkdir -p www -cp ./src/client/*.html ./www/ -cp ./src/client/*.css ./www/ - -mkdir -p www/js -cp ./src/client/*.js ./www/js/ - -mkdir -p www/js/class -cp ./src/client/class/*.js ./www/js/class/ - -mkdir -p www/shared_js/ -cp ./src/shared_js/*.js ./www/shared_js/ - -mkdir -p www/shared_js/class -cp ./src/shared_js/class/*.js ./www/shared_js/class/ diff --git a/JEU2/memo.txt b/JEU2/memo.txt deleted file mode 100644 index 20d493f3..00000000 --- a/JEU2/memo.txt +++ /dev/null @@ -1,45 +0,0 @@ -Done: - - Connexion client/serveur via un Websocket - - implémentation basique (authoritative server) - - Matchmaking - - client prediction - - server reconciliation (buffer des inputs côté client + id sur les inputs) - - amélioration collision avec Hugo - - du son (rebonds de la balle, "Oof" de Roblox sur un point) - - init de GameComponents partagé entre serveur et client. - - draw on the canvas "WIN", "LOSE", "MATCHMAKING COMPLETE", ... - - interpolation (mis à jour progressif des mouvements de l'adversaire) - - traitement groupé des inputs clients toutes les x millisecondes - (BUG désynchronisation: revenu à un traitement immédiat en attendant) - - Détruire les GameSession une fois finies. - - mode multi-balles - - mode murs mouvant (la zone de jeu rétréci / agrandi en continu) - - Selection des modes de jeu via HTML - - Selection audio on/off via HTML - -TODO: -- Match Abort si tout les joueurs ne sont pas pret assez vite (~15 secondes) -- mode spectateur -- certaines utilisations de Math.floor() superflu ? Vérifier les appels. - (éventuellement Math.round() ?) -- un autre mode de jeu alternatif ? -- changer les "localhost:8080" dans le code. -- sélection couleur des raquettes (your color/opponent color) dans le profil utilisateur. - Enregistrement dans la DB. - init des couleurs dans GameComponentsClient() basé sur les variables de l'utilsateur connecté. ------------ -idées modes de jeu : - - mode 2 raquettes (un joueur haut/gauche et bas/droite) - - skin patate ??? -- (prediction de l'avancement de la balle basé sur la latence serveur ?) -- d'autres sons (foule qui applaudi/musique de victoire) ------------ -- BUG: Si la balle va très vite, elle peut ignorer la collision avec une raquette ou mur. -la collision est testée seulement après le mouvement. -Pour éviter ce bug il faudrait diviser le mouvement pour faire plusieurs tests de collision successifs. -- BUG mineur: sur un changement de fenêtre, les touches restent enfoncées et il faut les "décoincer" -en réappuyant. Ce n'est pas grave mais peut-on faire mieux ? ----------- -OSEF, rebuts: -- reconnection -- amélioration du protocole, remplacement du JSON (compression. moins de bande passante). diff --git a/JEU2/src/server/class/Event.ts b/JEU2/src/server/class/Event.ts deleted file mode 100644 index 3f0d440a..00000000 --- a/JEU2/src/server/class/Event.ts +++ /dev/null @@ -1,107 +0,0 @@ - -import * as en from "../enums.js" - -/* From Server */ -class ServerEvent { - type: en.EventTypes; - constructor(type: en.EventTypes = 0) { - this.type = type; - } -} - -class EventAssignId extends ServerEvent { - id: string; - constructor(id: string) { - super(en.EventTypes.assignId); - this.id = id; - } -} - -class EventMatchmakingComplete extends ServerEvent { - side: en.PlayerSide; - constructor(side: en.PlayerSide) { - super(en.EventTypes.matchmakingComplete); - this.side = side; - } -} - -class EventGameUpdate extends ServerEvent { - playerLeft = { - y: 0 - }; - playerRight = { - y: 0 - }; - ballsArr: { - x: number, - y: number, - dirX: number, - dirY: number, - speed: number - }[] = []; - wallTop? = { - y: 0 - }; - wallBottom? = { - y: 0 - }; - lastInputId = 0; - constructor() { // TODO: constructor that take GameComponentsServer maybe ? - super(en.EventTypes.gameUpdate); - } -} - -class EventScoreUpdate extends ServerEvent { - scoreLeft: number; - scoreRight: number; - constructor(scoreLeft: number, scoreRight: number) { - super(en.EventTypes.scoreUpdate); - this.scoreLeft = scoreLeft; - this.scoreRight = scoreRight; - } -} - -class EventMatchEnd extends ServerEvent { - winner: en.PlayerSide; - constructor(winner: en.PlayerSide) { - super(en.EventTypes.matchEnd); - this.winner = winner; - } -} - - -/* From Client */ -class ClientEvent { - type: en.EventTypes; // readonly ? - constructor(type: en.EventTypes = 0) { - this.type = type; - } -} - -class ClientAnnounce extends ClientEvent { - role: en.ClientRole; - clientId: string; - matchOptions: en.MatchOptions; - constructor(role: en.ClientRole, matchOptions: en.MatchOptions, clientId: string = "") { - super(en.EventTypes.clientAnnounce); - this.role = role; - this.clientId = clientId; - this.matchOptions = matchOptions; - } -} - -class EventInput extends ClientEvent { - input: en.InputEnum; - id: number; - constructor(input: en.InputEnum = en.InputEnum.noInput, id: number = 0) { - super(en.EventTypes.clientInput); - this.input = input; - this.id = id; - } -} - -export { - ServerEvent, EventAssignId, EventMatchmakingComplete, - EventGameUpdate, EventScoreUpdate, EventMatchEnd, - ClientEvent, ClientAnnounce, EventInput -} diff --git a/JEU2/src/server/class/GameSession.ts b/JEU2/src/server/class/GameSession.ts deleted file mode 100644 index f10dccdf..00000000 --- a/JEU2/src/server/class/GameSession.ts +++ /dev/null @@ -1,188 +0,0 @@ - -import * as en from "../enums.js" -import * as ev from "./Event.js" -import * as c from "../constants.js" -import { ClientPlayer } from "./Client"; -import { GameComponentsServer } from "./GameComponentsServer.js"; -import { clientInputListener } from "../wsServer.js"; -import { random } from "../utils.js"; -import { Ball } from "../../shared_js/class/Rectangle.js"; -import { wallsMovements } from "../../shared_js/wallsMovement.js"; - -/* - Arg "s: GameSession" replace "this: GameSession" for use with setTimeout(), - because "this" is equal to "this: Timeout" -*/ -class GameSession { - id: string; // url ? - playersMap: Map = new Map(); - unreadyPlayersMap: Map = new Map(); - gameLoopInterval: NodeJS.Timer | number = 0; - clientsUpdateInterval: NodeJS.Timer | number = 0; - components: GameComponentsServer; - matchOptions: en.MatchOptions; - matchEnded: boolean = false; - - actual_time: number; - last_time: number; - delta_time: number; - - constructor(id: string, matchOptions: en.MatchOptions) { - this.id = id; - this.matchOptions = matchOptions; - this.components = new GameComponentsServer(this.matchOptions); - } - start() { - const gc = this.components; - setTimeout(this.resume, c.matchStartDelay, this); - - let timeout = c.matchStartDelay + c.newRoundDelay; - gc.ballsArr.forEach((ball) => { - setTimeout(this._newRound, timeout, this, ball); - timeout += c.newRoundDelay*0.5; - }); - } - resume(s: GameSession) { - s.playersMap.forEach( (client) => { - client.socket.on("message", clientInputListener); - }); - - s.actual_time = Date.now(); - s.gameLoopInterval = setInterval(s._gameLoop, c.serverGameLoopIntervalMS, s); - s.clientsUpdateInterval = setInterval(s._clientsUpdate, c.clientsUpdateIntervalMS, s); - } - pause(s: GameSession) { - s.playersMap.forEach( (client) => { - client.socket.off("message", clientInputListener); - }); - - clearInterval(s.gameLoopInterval); - clearInterval(s.clientsUpdateInterval); - } - instantInputDebug(client: ClientPlayer) { - this._handleInput(c.fixedDeltaTime, client); - } - private _handleInput(delta: number, client: ClientPlayer) { - // if (client.inputBuffer === null) {return;} - const gc = this.components; - const input = client.inputBuffer.input; - - if (input === en.InputEnum.up) { - client.racket.dir.y = -1; - } - else if (input === en.InputEnum.down) { - client.racket.dir.y = 1; - } - - if (input !== en.InputEnum.noInput) { - client.racket.moveAndCollide(delta, [gc.wallTop, gc.wallBottom]); - } - - client.lastInputId = client.inputBuffer.id; - // client.inputBuffer = null; - } - private _gameLoop(s: GameSession) { - /* s.last_time = s.actual_time; - s.actual_time = Date.now(); - s.delta_time = (s.actual_time - s.last_time) / 1000; */ - s.delta_time = c.fixedDeltaTime; - - // WIP, replaced by instantInputDebug() to prevent desynchro - /* s.playersMap.forEach( (client) => { - s._handleInput(s.delta_time, client); - }); */ - - const gc = s.components; - gc.ballsArr.forEach((ball) => { - s._ballMovement(s.delta_time, ball); - }); - - if (s.matchOptions & en.MatchOptions.movingWalls) { - wallsMovements(s.delta_time, gc); - } - } - private _ballMovement(delta: number, ball: Ball) { - const gc = this.components; - if (ball.ballInPlay) - { - ball.moveAndBounce(delta, [gc.wallTop, gc.wallBottom, gc.playerLeft, gc.playerRight]); - if (ball.pos.x > c.w - || ball.pos.x < 0 - ball.width) - { - ball.ballInPlay = false; - if (this.matchEnded) { - return; - } - - if (ball.pos.x > c.w) { ++gc.scoreLeft; } - else if (ball.pos.x < 0 - ball.width) { ++gc.scoreRight; } - - this.playersMap.forEach( (client) => { - client.socket.send(JSON.stringify(new ev.EventScoreUpdate(gc.scoreLeft, gc.scoreRight))); - }); - setTimeout(this._newRound, c.newRoundDelay, this, ball); - } - } - } - private _clientsUpdate(s: GameSession) { - const gc = s.components; - const update = new ev.EventGameUpdate(); - update.playerLeft.y = gc.playerLeft.pos.y; - update.playerRight.y = gc.playerRight.pos.y; - gc.ballsArr.forEach((ball) => { - update.ballsArr.push({ - x: ball.pos.x, - y: ball.pos.y, - dirX: ball.dir.x, - dirY: ball.dir.y, - speed: ball.speed - }); - }); - if (s.matchOptions & en.MatchOptions.movingWalls) { - update.wallTop.y = gc.wallTop.pos.y; - update.wallBottom.y = gc.wallBottom.pos.y; - } - - s.playersMap.forEach( (client) => { - update.lastInputId = client.lastInputId; - client.socket.send(JSON.stringify(update)); - }); - } - private _newRound(s: GameSession, ball: Ball) { - const gc = s.components; - // https://fr.wikipedia.org/wiki/Tennis_de_table#Nombre_de_manches - if (gc.scoreLeft >= 11 || gc.scoreRight >= 11) - // if (gc.scoreLeft >= 2 || gc.scoreRight >= 2) // WIP: for testing - { - if (Math.abs(gc.scoreLeft - gc.scoreRight) >= 2) - { - s._matchEnd(s); - return; - } - } - ball.pos.x = c.w_mid; - ball.pos.y = random(c.h*0.3, c.h*0.7); - ball.speed = ball.baseSpeed; - ball.ballInPlay = true; - } - private _matchEnd(s: GameSession) { - s.matchEnded = true; - const gc = s.components; - - let eventEnd: ev.EventMatchEnd; - if (gc.scoreLeft > gc.scoreRight) { - eventEnd = new ev.EventMatchEnd(en.PlayerSide.left); - console.log("Player Left WIN"); - } - else { - eventEnd = new ev.EventMatchEnd(en.PlayerSide.right); - console.log("Player Right WIN"); - } - - s.playersMap.forEach( (client) => { - client.socket.send(JSON.stringify(eventEnd)); - }); - } -} - -export {GameSession} diff --git a/JEU2/src/server/server.ts b/JEU2/src/server/server.ts deleted file mode 100644 index 20801d7f..00000000 --- a/JEU2/src/server/server.ts +++ /dev/null @@ -1,41 +0,0 @@ - -import http from "http"; -import url from "url"; -import fs from "fs"; -import path from "path"; - -import {wsServer} from "./wsServer.js"; wsServer; // no-op, just for loading - -const hostname = "localhost"; -const port = 8080; -const root = "../../www/"; - -const server = http.createServer((req, res) => { - // let q = new URL(req.url, `http://${req.getHeaders().host}`) - let q = url.parse(req.url, true); - let filename = root + q.pathname; - fs.readFile(filename, (err, data) => { - if (err) { - res.writeHead(404, {"Content-Type": "text/html"}); - return res.end("404 Not Found"); - } - if (path.extname(filename) === ".html") { - res.writeHead(200, {"Content-Type": "text/html"}); - } - else if (path.extname(filename) === ".js") { - res.writeHead(200, {"Content-Type": "application/javascript"}); - } - else if (path.extname(filename) === ".mp3") { - res.writeHead(200, {"Content-Type": "audio/mpeg"}); - } - else if (path.extname(filename) === ".ogg") { - res.writeHead(200, {"Content-Type": "audio/ogg"}); - } - res.write(data); - return res.end(); - }); -}); - -server.listen(port, hostname, () => { - console.log(`Pong running at http://${hostname}:${port}/pong.html`); -}); diff --git a/JEU2/src/server/utils.ts b/JEU2/src/server/utils.ts deleted file mode 100644 index 39929054..00000000 --- a/JEU2/src/server/utils.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { MovingRectangle } from "./class/Rectangle.js"; -export * from "../shared_js/utils.js" - -function shortId(id: string): string { - return id.substring(0, id.indexOf("-")); -} - -export {shortId} - -function random(min: number = 0, max: number = 1) { - return Math.random() * (max - min) + min; -} - -function sleep (ms: number) { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - -function clamp(n: number, min: number, max: number) : number -{ - if (n < min) - n = min; - else if (n > max) - n = max; - return (n); -} - -// Typescript hack, unused -function assertMovingRectangle(value: unknown): asserts value is MovingRectangle { - // if (value !== MovingRectangle) throw new Error("Not a MovingRectangle"); - return; -} - -export {random, sleep, clamp, assertMovingRectangle} diff --git a/JEU2/src/server/wsServer.ts b/JEU2/src/server/wsServer.ts deleted file mode 100644 index bc3901bc..00000000 --- a/JEU2/src/server/wsServer.ts +++ /dev/null @@ -1,238 +0,0 @@ - -import { WebSocketServer, WebSocket as BaseLibWebSocket } from "ws"; - -export class WebSocket extends BaseLibWebSocket { - id?: string; -} - -import { IncomingMessage } from "http"; -import { v4 as uuidv4 } from 'uuid'; - -import * as en from "./enums.js" -import * as ev from "./class/Event.js" -import { Client, ClientPlayer } from "./class/Client.js" -import { GameSession } from "./class/GameSession.js" -import { shortId } from "./utils.js"; - -// pas indispensable d'avoir un autre port si le WebSocket est relié à un serveur http préexistant ? -const wsPort = 8042; -export const wsServer = new WebSocketServer({port: wsPort, path: "/pong"}); - -const clientsMap: Map = new Map; // socket.id/Client -const matchmakingPlayersMap: Map = new Map; // socket.id/ClientPlayer (duplicates with clientsMap) -const gameSessionsMap: Map = new Map; // GameSession.id(url)/GameSession - -wsServer.on("connection", connectionListener); -wsServer.on("error", errorListener); -wsServer.on("close", closeListener); - - -function connectionListener(socket: WebSocket, request: IncomingMessage) -{ - const id = uuidv4(); - const client = new Client(socket, id); - clientsMap.set(id, client); - socket.id = id; - - socket.on("pong", function heartbeat() { - client.isAlive = true; - // console.log(`client ${shortId(client.id)} is alive`); - }); - - socket.on("message", function log(data: string) { - try { - const event: ev.ClientEvent = JSON.parse(data); - if (event.type === en.EventTypes.clientInput) { - return; - } - } - catch (e) {} - console.log("data: " + data); - }); - - socket.once("message", clientAnnounceListener); -} - - -function clientAnnounceListener(this: WebSocket, data: string) -{ - try { - const msg : ev.ClientAnnounce = JSON.parse(data); - if (msg.type === en.EventTypes.clientAnnounce) - { - // TODO: reconnection with msg.clientId ? - // TODO: spectator/player distinction with msg.role ? - // msg.role is probably not a good idea. - // something like a different route could be better - // "/pong" to play, "/ID_OF_A_GAMESESSION" to spectate - - const player = clientsMap.get(this.id) as ClientPlayer; - player.matchOptions = msg.matchOptions; - this.send(JSON.stringify( new ev.EventAssignId(this.id) )); - this.send(JSON.stringify( new ev.ServerEvent(en.EventTypes.matchmakingInProgress) )); - matchmaking(player); - } - else { - console.log("Invalid ClientAnnounce"); - } - return; - } - catch (e) { - console.log("Invalid JSON (clientAnnounceListener)"); - } - this.once("message", clientAnnounceListener); -} - - -function matchmaking(player: ClientPlayer) -{ - const minPlayersNumber = 2; - const maxPlayersNumber = 2; - const matchOptions = player.matchOptions; - matchmakingPlayersMap.set(player.id, player); - - const compatiblePlayers: ClientPlayer[] = []; - for (const [id, client] of matchmakingPlayersMap) - { - if (client.matchOptions === matchOptions) - { - compatiblePlayers.push(client); - if (compatiblePlayers.length === maxPlayersNumber) { - break; - } - } - } - - if (compatiblePlayers.length < minPlayersNumber) { - return; - } - - const id = uuidv4(); - const gameSession = new GameSession(id, matchOptions); - gameSessionsMap.set(id, gameSession); - - compatiblePlayers.forEach((client) => { - matchmakingPlayersMap.delete(client.id); - client.gameSession = gameSession; - gameSession.playersMap.set(client.id, client); - gameSession.unreadyPlayersMap.set(client.id, client); - }); - - // WIP: Not pretty, hardcoded two players. - // Could be done in gameSession maybe ? - compatiblePlayers[0].racket = gameSession.components.playerRight; - compatiblePlayers[1].racket = gameSession.components.playerLeft; - - compatiblePlayers.forEach((client) => { - client.socket.once("message", playerReadyConfirmationListener); - }); - - compatiblePlayers[0].socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.right) )); - compatiblePlayers[1].socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.left) )); -} - - -function playerReadyConfirmationListener(this: WebSocket, data: string) -{ - try { - const msg : ev.ClientEvent = JSON.parse(data); - if (msg.type === en.EventTypes.clientPlayerReady) - { - const client = clientsMap.get(this.id); - const gameSession = client.gameSession; - gameSession.unreadyPlayersMap.delete(this.id); - if (gameSession.unreadyPlayersMap.size === 0) { - gameSession.playersMap.forEach( (client) => { - client.socket.send(JSON.stringify( new ev.ServerEvent(en.EventTypes.matchStart) )); - }); - gameSession.start(); - } - } - else { - console.log("Invalid playerReadyConfirmation"); - } - return; - } - catch (e) { - console.log("Invalid JSON (playerReadyConfirmationListener)"); - } - this.once("message", playerReadyConfirmationListener); -} - - -export function clientInputListener(this: WebSocket, data: string) -{ - try { - // const input: ev.ClientEvent = JSON.parse(data); - const input: ev.EventInput = JSON.parse(data); - if (input.type === en.EventTypes.clientInput) - { - const client = clientsMap.get(this.id) as ClientPlayer; - client.inputBuffer = input; - client.gameSession.instantInputDebug(client); // wip - } - else { - console.log("Invalid clientInput"); - } - } - catch (e) { - console.log("Invalid JSON (clientInputListener)"); - } -} - -//////////// -//////////// - -const pingInterval = setInterval( () => { - let deleteLog = ""; - clientsMap.forEach( (client, key, map) => { - if (!client.isAlive) { - clientTerminate(client, key, map); - deleteLog += ` ${shortId(key)} |`; - } - else { - client.isAlive = false; - client.socket.ping(); - } - }); - - if (deleteLog) { - console.log(`Disconnected:${deleteLog}`); - } - console.log("gameSessionMap size: " + gameSessionsMap.size); - console.log("clientsMap size: " + clientsMap.size); - console.log("matchmakingPlayersMap size: " + matchmakingPlayersMap.size); - console.log(""); -}, 4200); - - -function clientTerminate(client: Client, key: string, map: Map) -{ - client.socket.terminate(); - if (client.gameSession) - { - client.gameSession.playersMap.delete(key); - if (client.gameSession.playersMap.size === 0) - { - clearInterval(client.gameSession.clientsUpdateInterval); - clearInterval(client.gameSession.gameLoopInterval); - gameSessionsMap.delete(client.gameSession.id); - } - } - map.delete(key); - if (matchmakingPlayersMap.has(key)) { - matchmakingPlayersMap.delete(key); - } -} - - -function closeListener() -{ - clearInterval(pingInterval); -} - - -function errorListener(error: Error) -{ - console.log("Error: " + JSON.stringify(error)); -} diff --git a/JEU2/tsconfig.json b/JEU2/tsconfig.json deleted file mode 100644 index 988126ba..00000000 --- a/JEU2/tsconfig.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "include": ["src"], -// "exclude": ["node_modules"], - "compilerOptions": { - // "outDir": "./build", - // "types": ["node"], /* Specify type package names to be included without being referenced in a source file. */ - /* Visit https://aka.ms/tsconfig to read more about this file */ - - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - - /* Language and Environment */ - "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.gc. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.gc. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - - /* Modules */ - // "module": "commonjs", /* Specify what module code is generated. */ - "module": "ES6", /* Specify what module code is generated. */ - // "rootDir": "./", /* Specify the root folder within your source files. */ - "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - // "resolveJsonModule": true, /* Enable importing .json files. */ - // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ - - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ - - /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - "strictNullChecks": false, /* When type checking, take into account 'null' and 'undefined'. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } -} diff --git a/Makefile b/Makefile index ba00eaec..10e8bccb 100644 --- a/Makefile +++ b/Makefile @@ -1,44 +1,28 @@ DOCKERCOMPOSEPATH=./srcs/docker-compose.yml #dev allow hot reload. -dev: +up: + @bash ./make_env.sh docker compose -f ${DOCKERCOMPOSEPATH} up -d --build @make start @docker ps - -#prod only the needed files ares presents inside the container -prod: - docker compose -f ${DOCKERCOMPOSEPATH} up -d --build prod - @make start_prod - @docker ps - start: docker compose -f ${DOCKERCOMPOSEPATH} start - docker logs --follow srcs-backend_dev-1 + docker logs --follow nestjs -start_dev: - docker compose -f ${DOCKERCOMPOSEPATH} start dev - docker logs --follow srcs-backend_dev-1 +all : up -start_prod: - docker compose -f ${DOCKERCOMPOSEPATH} start prod - -restart:stop - @make up +re: down up down: docker compose -f ${DOCKERCOMPOSEPATH} -v down destroy: - # rm -rf ./srcs/requirements/nestjs/api_back/node_modules/ - # rm -rf ./srcs/requirements/nestjs/api_back/dist - # rm -rf ./srcs/requirements/svelte/api_front/node_modules/ - # rm -rf ./srcs/requirements/svelte/api_front/public/build - docker compose -f ${DOCKERCOMPOSEPATH} down -v --rmi all --remove-orphans - docker ps -aq | xargs --no-run-if-empty docker rm -f - docker images -aq | xargs --no-run-if-empty docker rmi -f - docker volume ls -q | xargs --no-run-if-empty docker volume rm + - docker compose -f ${DOCKERCOMPOSEPATH} down -v --rmi all --remove-orphans + - docker ps -aq | xargs --no-run-if-empty docker rm -f + - docker images -aq | xargs --no-run-if-empty docker rmi -f + - docker volume ls -q | xargs --no-run-if-empty docker volume rm stop: docker compose -f ${DOCKERCOMPOSEPATH} stop diff --git a/README.md b/README.md index ffefe99a..1e5589a2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +- CONFLICT srcs/requirements/svelte/api_front/public/build/bundle.js +- CONFLICT srcs/requirements/svelte/api_front/public/build/bundle.js.map + + ### Pour lancer le docker : - Il faut un fichier .env qu'on ne doit pas push, donc je ne le push pas. @@ -6,60 +10,28 @@ - Il faut le placer au même endroit que docker-compose.yml - Dans le makefile il y a un sedf pour changer l'un ou l'autre. +- also add an alias for transcendance in /etc/hosts + ### TODO List : Utilisateur édition. - [x] Utilisateur : faire la base pour un utilisateur - [x] Utilisateur : faire le système de requêtes amis -- [ ] Utilisateur : mettre en place le système de session (voire de statut ?) -- [ ] Utilisateur : mettre en place le système d'avatar -- [ ] Utilisateur : mettre en place la double authentification -- [ ] Utilisateur : mettre en place le système d'Oauth -- [ ] Utilisateur : mettre en place la hashage de mot de passe (avec Oauth) -- [ ] Utilisateur : mettre en place le système de statut -- [ ] Utilisateur : mettre en place le système de stats -- [ ] Utilisateur : mettre en place l'historique des matches +- [x] Utilisateur : mettre en place le système de session (voire de statut ?) +- [x] Utilisateur : mettre en place le système d'avatar +- [x] Utilisateur : mettre en place la double authentification +- [x] Utilisateur : mettre en place le système d'Oauth +- [x] Utilisateur : mettre en place la hashage de mot de passe (avec Oauth) +- [x] Utilisateur : mettre en place le système de statut +- [x] Utilisateur : mettre en place le système de stats +- [x] Utilisateur : mettre en place l'historique des matches ### TODO List : Docker édition. - [ ] Docker : trouver un moyen simple de générer un .env. Peut-être renouveller les clé à chaque lancement. - -## questions : - -- choose a secondary browser -- choose solution to rootless mode (VM, rebuild, unique root uid) -- choose 2fa method : texto ? Google Authentication ? -- when chat-room owner leaves what happens ? -- can chat-room administrators ban and mute other administrators ? -- game technologie (canvas ?) - ---- - -## tasks : - -#### luke - -- getting started with Javascript -- getting started with Node.js/Nest.js -- pong game solo front-end (canvas ? js ?) -- add multiplayers to Pong with Node.js (without database, accounts, ...) - -#### eric - -- getting started with Javascript -- getting started with framework TypeScript front-end (Svelte ?) -- single-page démo, sans back-end -- chat front-end ? (tester avec des messages random locaux) - -#### hugo - -- getting started with Javascript -- getting started with Node.js/Nest.js -- getting started with PostgreSQL - --- ## instructions : @@ -82,70 +54,81 @@ #### security concerns : - [ ] hash every passwords in db - - [ ] protection against SQL injections - - [ ] server-side validation of users inputs - - [ ] store credentials in local .env git-ignored #### user account : - [ ] login with 42 intranet OAuth system - - [ ] user can choose name, avatar, 2fa (ex texto or Google Authenticator) - - [ ] display user name on site - - [ ] user default avatar if not chosen - - [ ] user can add friends, and see status (online/offline, in game, ...) - - [ ] display stats on user profile (wins, losses, ladderm levelm achievements, ...) - - [ ] public match history (lvl games, ladder, ...) #### chat : - [ ] can create chat-rooms (public/private, password protected) - - [ ] send direct messages - - [ ] block other users - - [ ] creators of chat-room are owners, untill they leave - - [ ] chat-room owner can set, change, remove password - - [ ] chat-room owner is administrator and can set other administrators - - [ ] administrators can ban or mute for a time other users - - [ ] send game invitation in chat - - [ ] view user profiles from chat #### game : - [ ] play pong with others on website - - [ ] matchmaking system : join a queue untill automatic match - - [ ] faithfull to original pong (1972) - - [ ] customs options (powers up, multiple maps, ...), with a default one - - [ ] reponsive - - [ ] can watch other matchs --- ## Resources +- [routes back](https://semestriel.framapad.org/p/z5gqbq51dx-9xlo?lang=fr) + +### error msg +- [rollup packages did not export](https://stackoverflow.com/questions/69768925/rollup-plugin-svelte-the-following-packages-did-not-export-their-package-json) + ### Svelte - [The Official Svelte Tutorial](https://svelte.dev/tutorial/basics) - SPA Svelte Article [Build a single-page application in Svelte with svelte-spa-router](https://blog.logrocket.com/build-spa-svelte-svelte-spa-router/) - [An excellent Svelt Tutorial video series](https://www.youtube.com/watch?v=zojEMeQGGHs&list=PL4cUxeGkcC9hlbrVO_2QFVqVPhlZmz7tO&index=2) +- to check svelte logs, do a 'docker logs --follow ' + +### nestjs +- [linkedin clone angular nestjs](https://www.youtube.com/watch?v=gL3D-MIt_G8&list=PL9_OU-1M9E_ut3NA04C4eHZuuAFQOUwT0&index=1) +- [nestjs crash course](https://www.youtube.com/watch?v=vGafqCNCCSs) + +### websocket +- [game networking](https://gafferongames.com/post/what_every_programmer_needs_to_know_about_game_networking/) +- [client-server game architecture](https://www.gabrielgambetta.com/client-server-game-architecture.html) +- [websocket api mozilla doc](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) +- [websocket rfc](https://www.rfc-editor.org/rfc/rfc6455.html) +- [ws doc npm](https://www.npmjs.com/package/ws) +- [exemple chat implementation](https://github.com/mdn/samples-server/tree/master/s/websocket-chat) +- [websocket and nginx](https://www.nginx.com/blog/websocket-nginx/) + +### css +- [separation of concern](https://adamwathan.me/css-utility-classes-and-separation-of-concerns/) +- [decoupling css and html](https://www.smashingmagazine.com/2012/04/decoupling-html-from-css/) + +### security +- [xss attack with innerHTML](https://gomakethings.com/a-safer-alternative-to-innerhtml-with-vanilla-js/) +- [xss attack innerHTML prevention](https://stackoverflow.com/questions/30661497/xss-prevention-and-innerhtml) +- [xss attack prevention with createTextNode](https://stackoverflow.com/questions/11654555/is-createtextnode-completely-safe-from-html-injection-xss) +- [xss attacks prevention in svelte](https://stackoverflow.com/questions/74931516/in-svete-what-to-use-instead-of-html-to-avoid-xss-attacks/74932137) + +### installation +- [node and npm with nvm](https://github.com/nvm-sh/nvm) +- [docker](https://github.com/docker/docker-install) diff --git a/Docs/Vue_ensemble_transcendance.html b/docs/Vue_ensemble_transcendance.html similarity index 99% rename from Docs/Vue_ensemble_transcendance.html rename to docs/Vue_ensemble_transcendance.html index ab74b3fc..39ba9f0d 100644 --- a/Docs/Vue_ensemble_transcendance.html +++ b/docs/Vue_ensemble_transcendance.html @@ -8,4 +8,4 @@
- \ No newline at end of file + diff --git a/docs/transcendence_chat.drawio.html b/docs/transcendence_chat.drawio.html new file mode 100644 index 00000000..74a3aafc --- /dev/null +++ b/docs/transcendence_chat.drawio.html @@ -0,0 +1,12 @@ + + + + +transcendence_chat.drawio.html + + + +
+ + + diff --git a/docs/transcendence_en.subject.pdf b/docs/transcendence_en.subject.pdf new file mode 100644 index 00000000..e1154ffc Binary files /dev/null and b/docs/transcendence_en.subject.pdf differ diff --git a/make_env.sh b/make_env.sh new file mode 100755 index 00000000..7c218de4 --- /dev/null +++ b/make_env.sh @@ -0,0 +1,148 @@ +#! /usr/bin/env bash + +ENV_FILE_DOCKER=./srcs/.env +ENV_FILE_SVELTE=./srcs/requirements/svelte/api_front/.env +NGINX_CONF_FILE=./srcs/requirements/nginx/conf/default.conf +BOLD_RED="\033[1;31m" +BOLD_GREEN="\033[1;32m" +BOLD_BLUE="\033[1;34m" +RESET="\033[0m" + +# Function to generate passwords +# + function generate_password + { + # base64 alphabet is alphanumeric characters and "+", "/", "=" + # https://en.wikipedia.org/wiki/Base64#Base64_table_from_RFC_4648 + # we could delete them 'tr -d "+/="', but that would randomly shorten the string + echo $(openssl rand -base64 32 | tr "/" "_" ); + } + + function make_env_for_svelte + { + echo -e "${BOLD_BLUE}Creating a new environment for svelte${RESET}" + grep "^WEBSITE_" "$ENV_FILE_DOCKER" > "$ENV_FILE_SVELTE" + } + + function update_nginx_conf + { + echo -e "${BOLD_BLUE}Updating the nginx conf${RESET}" + echo -e "${BOLD_RED}WARNING : If for some reason you've changed the port, you MUST change it inside the nginx conf file. It's not supposed to change.${RESET}" + HOST=$(grep "^WEBSITE_HOST" $ENV_FILE_DOCKER | cut -d "=" -f 2) + sed -i "s/server_name.*/server_name $HOST;/g" "$NGINX_CONF_FILE" + } + + function make_env_for_docker_and_svelte + { + docker rm -f postgresql + docker volume rm -f srcs_data_nest_postgresql + echo -e "${BOLD_BLUE}Creating a new environment for docker${RESET}" + NODE_ENV="" + # Ask if dev or prod environment + while [ "$NODE_ENV" != "1" ] && [ "$NODE_ENV" != "2" ]; do + read -p "Enter the env configuration for nestjs : \"1\" for development OR \"2\" for production : " NODE_ENV + done + if [ "$NODE_ENV" = "1" ]; then + echo "NODE_ENV=development" > "$ENV_FILE_DOCKER" + else + echo "NODE_ENV=production" > "$ENV_FILE_DOCKER" + fi + read -p "Enter the name of the host like \"localhost\" : " PROJECT_HOST + echo "WEBSITE_HOST=$PROJECT_HOST" >> "$ENV_FILE_DOCKER" + echo "WEBSITE_PORT=8080" >> "$ENV_FILE_DOCKER" + echo "POSTGRES_USER=postgres" >> "$ENV_FILE_DOCKER" + echo "#if change postgres pswd, do make destroy" >> "$ENV_FILE_DOCKER" + echo "POSTGRES_PASSWORD=$(generate_password)" >> "$ENV_FILE_DOCKER" + echo "POSTGRES_DB=transcendance_db" >> "$ENV_FILE_DOCKER" + echo "POSTGRES_HOST=postgresql" >> "$ENV_FILE_DOCKER" + echo "POSTGRES_PORT=5432" >> "$ENV_FILE_DOCKER" + echo "REDIS_HOST=redis" >> "$ENV_FILE_DOCKER" + echo "REDIS_PORT=6379" >> "$ENV_FILE_DOCKER" + echo "REDIS_PASSWORD=$(generate_password)" >> "$ENV_FILE_DOCKER" + # Connection to 42 + echo -e "${BOLD_BLUE}In the next steps, we'll need to enter the client secret and client id of the 42 api${RESET}" + read -p "Enter the client id of the 42 api : " CLIENT_ID + echo "FORTYTWO_CLIENT_ID=$CLIENT_ID" >> "$ENV_FILE_DOCKER" + read -p "Enter the client secret of the 42 api : " CLIENT_SECRET + echo "FORTYTWO_CLIENT_SECRET=$CLIENT_SECRET" >> "$ENV_FILE_DOCKER" + FT_CALLBACK="http://$PROJECT_HOST:8080/api/v2/auth/redirect" + echo "FORTYTWO_CALLBACK_URL=$FT_CALLBACK" >> "$ENV_FILE_DOCKER" + # Other configs + echo "COOKIE_SECRET=$(generate_password)" >> "$ENV_FILE_DOCKER" + echo "PORT=3000" >> "$ENV_FILE_DOCKER" + echo "TWO_FACTOR_AUTHENTICATION_APP_NAME=Transcendance" >> "$ENV_FILE_DOCKER" + echo "TICKET_FOR_PLAYING_GAME_SECRET=$(generate_password)" >> "$ENV_FILE_DOCKER" + make_env_for_svelte + update_nginx_conf + echo -e "${BOLD_GREEN}Environment created.${RESET}" + echo -e "${BOLD_GREEN}The script will exit${RESET}" + exit 0 + } + + function change_host_and_port_api + { + if [ -f "$ENV_FILE_DOCKER" ] + then + echo -e "${BOLD_BLUE}Changing the host and the port of the api${RESET}" + read -p "Enter the name of the host like \"localhost\" : " PROJECT_HOST + sed -i "s/WEBSITE_HOST=.*/WEBSITE_HOST=$PROJECT_HOST/g" "$ENV_FILE_DOCKER" + read -p "Enter the port of the api : " PROJECT_PORT + sed -i "s/WEBSITE_PORT=.*/WEBSITE_PORT=$PROJECT_PORT/g" "$ENV_FILE_DOCKER" + make_env_for_svelte + update_nginx_conf + else + echo -e "${BOLD_RED}No environment file found. We will regenerate the entire env files.${RESET}" + fi + } + + function change_api_fields_for_42_auth_api + { + if [ -f "$ENV_FILE_DOCKER" ] + then + echo -e "${BOLD_BLUE}Changing the secret for the 42 api${RESET}" + read -p "Enter the client id of the 42 api : " CLIENT_ID + sed -i "s/FORTYTWO_CLIENT_ID=.*/FORTYTWO_CLIENT_ID=$CLIENT_ID/g" "$ENV_FILE_DOCKER" + read -p "Enter the client secret of the 42 api : " CLIENT_SECRET + sed -i "s/FORTYTWO_CLIENT_SECRET=.*/FORTYTWO_CLIENT_SECRET=$CLIENT_SECRET/g" "$ENV_FILE_DOCKER" + echo -e "${BOLD_GREEN}The fields concerning the 42 api have been changed.${RESET}" + else + echo -e "${BOLD_RED}No environment file found. We will regenerate the entire env files.${RESET}" + make_env_for_docker_and_svelte + fi + } + + + function choose_options_and_process { + if [ ! -f "$ENV_FILE_DOCKER" ]; then + make_env_for_docker_and_svelte + elif [ ! -f "$ENV_FILE_SVELTE" && -f "$ENV_FILE_DOCKER" ]; then + make_env_for_svelte + fi + echo -e "${BOLD_RED}An environment already exists.${RESET}" + echo -e "${BOLD_GREEN}What do you want to do ?${RESET}" + echo -e "${BOLD_GREEN}1. Regenerate entire environment${RESET}" + echo -e "${BOLD_GREEN}2. Only change the fields about the HOSTNAME and the PORT of the API${RESET}" + echo -e "${BOLD_GREEN}3. Only change the fields concerning the 42 API (id and secret)${RESET}" + echo -e "${BOLD_GREEN}4. Exit${RESET}" + CHOICE="" + while [ "$CHOICE" != "1" ] && [ "$CHOICE" != "2" ] && [ "$CHOICE" != "3" ] && [ "$CHOICE" != "4" ]; do + read -p "Enter your choice : " CHOICE + done + if [ "$CHOICE" = "1" ]; then + make_env_for_docker_and_svelte + elif [ "$CHOICE" = "2" ]; then + change_host_and_port_api + elif [ "$CHOICE" = "3" ]; then + change_api_fields_for_42_auth_api + else + echo -e "${BOLD_GREEN}The script will exit.${RESET}" + exit 0 + fi + } + +# Create a new environment for docker + + choose_options_and_process + + echo "The environment has been created successfully. You can now wait for the docker to build the project." + diff --git a/package-lock.json b/package-lock.json index da5fa458..48e341a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,3 @@ { - "name": "group_transcendence", - "lockfileVersion": 2, - "requires": true, - "packages": {} + "lockfileVersion": 1 } diff --git a/srcs/.env b/srcs/.env deleted file mode 100644 index a8fbadb8..00000000 --- a/srcs/.env +++ /dev/null @@ -1,9 +0,0 @@ -NODE_ENV=development -POSTGRES_USER=postgres -POSTGRES_PASSWORD=9pKpKEgiamxwk5P7Ggsz -POSTGRES_DB=transcendance_db -POSTGRES_HOST=postgresql -POSTGRES_PORT=5432 -REDIS_HOST=redis -REDIS_PORT=6379 -REDIS_PASSWORD=1a5e04138b91b3d683c708e4689454c2 diff --git a/srcs/docker-compose.yml b/srcs/docker-compose.yml index 62dc9479..3d6fa9c2 100644 --- a/srcs/docker-compose.yml +++ b/srcs/docker-compose.yml @@ -1,22 +1,54 @@ services: backend_dev: + container_name: nestjs build: context: ./requirements/nestjs target: development dockerfile: Dockerfile + environment: + POSTGRES_USER: "${POSTGRES_USER}" + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" + POSTGRES_DB: "${POSTGRES_DB}" + POSTGRES_HOST: "${POSTGRES_HOST}" + POSTGRES_PORT: "${POSTGRES_PORT}" + NODE_ENV: "${NODE_ENV}" + WEBSITE_HOST: "${WEBSITE_HOST}" + WEBSITE_PORT: "${WEBSITE_PORT}" + REDIS_HOST: "${REDIS_HOST}" + REDIS_PORT: "${REDIS_PORT}" + FORTYTWO_CLIENT_ID: "${FORTYTWO_CLIENT_ID}" + FORTYTWO_CLIENT_SECRET : "${FORTYTWO_CLIENT_SECRET}" + FORTYTWO_CALLBACK_URL: "${FORTYTWO_CALLBACK_URL}" + COOKIE_SECRET: "${COOKIE_SECRET}" + TWO_FACTOR_AUTHENTICATION_APP_NAME : "${TWO_FACTOR_AUTHENTICATION_APP_NAME}" + TICKET_FOR_PLAYING_GAME_SECRET : "${TICKET_FOR_PLAYING_GAME_SECRET}" + PORT: "${PORT}" volumes: - ./requirements/nestjs/api_back/src:/usr/app/src - ./requirements/nestjs/api_back/test:/usr/app/test/ - env_file: - - .env - environment: - NODE_ENV: "${NODE_ENV}" + - nestjs_photos_volume:/usr/app/src/uploads/avatars restart: unless-stopped depends_on: - postgresql - redis + game_server: + container_name: game_server + build: + context: ./requirements/game_server + dockerfile: Dockerfile + environment: + NODE_ENV: "${NODE_ENV}" + WEBSITE_HOST: "${WEBSITE_HOST}" + WEBSITE_PORT: "${WEBSITE_PORT}" + restart: unless-stopped + ports: + - "8042:8042" + depends_on: + - backend_dev + frontend_dev: + container_name: svelte build: context: ./requirements/svelte target: development @@ -26,9 +58,9 @@ services: - ./requirements/svelte/api_front/public:/usr/app/public/ ports: - "35729:35729" - env_file: - - .env environment: + WEBSITE_HOST: "${WEBSITE_HOST}" + WEBSITE_PORT: "${WEBSITE_PORT}" NODE_ENV: "${NODE_ENV}" restart: unless-stopped depends_on: @@ -38,10 +70,12 @@ services: # t'embete pas a gerer ton propre container nginx nginx: + container_name: nginx image: nginx:alpine restart: unless-stopped volumes: - ./requirements/nginx/conf/default.conf:/etc/nginx/conf.d/default.conf:ro + - ./requirements/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro command: [nginx-debug, "-g", "daemon off;"] ports: - "8080:8080" @@ -52,7 +86,7 @@ services: - redis postgresql: - container_name: nestjs_postgresql + container_name: postgresql image: postgres volumes: - data_nest_postgresql:/var/lib/postgresql/data @@ -66,10 +100,8 @@ services: # Je connais pas redis, mais si t'en a besoin que a l'interieur de tes containers, je pense pas que t'as besoin d'un expose. redis: - container_name: nestjs_redis + container_name: redis image: redis:alpine - expose: - - "6379" restart: unless-stopped environment: REDIS_HOST: "${REDIS_HOST}" @@ -77,3 +109,4 @@ services: volumes: data_nest_postgresql: + nestjs_photos_volume: diff --git a/srcs/requirements/game_server/Dockerfile b/srcs/requirements/game_server/Dockerfile new file mode 100644 index 00000000..72857a78 --- /dev/null +++ b/srcs/requirements/game_server/Dockerfile @@ -0,0 +1,15 @@ +FROM node:alpine AS build + +WORKDIR /usr/app + +COPY ./game_back ./ + +RUN npm install typescript + +RUN npx tsc + +WORKDIR /usr/app/src/server + +EXPOSE 8042 + +CMD [ "node", "wsServer.js"] diff --git a/JEU2/jsconfig.json b/srcs/requirements/game_server/game_back/jsconfig.json similarity index 100% rename from JEU2/jsconfig.json rename to srcs/requirements/game_server/game_back/jsconfig.json diff --git a/JEU2/package-lock.json b/srcs/requirements/game_server/game_back/package-lock.json similarity index 90% rename from JEU2/package-lock.json rename to srcs/requirements/game_server/game_back/package-lock.json index 807c07eb..414d8d22 100644 --- a/JEU2/package-lock.json +++ b/srcs/requirements/game_server/game_back/package-lock.json @@ -1,5 +1,5 @@ { - "name": "ft_transcendence", + "name": "game_back", "lockfileVersion": 2, "requires": true, "packages": { @@ -12,7 +12,7 @@ "@types/node": "^18.11.5", "@types/uuid": "^8.3.4", "@types/ws": "^8.5.3", - "typescript": "^4.8.4" + "typescript": "^4.9.4" } }, "node_modules/@types/node": { @@ -37,9 +37,9 @@ } }, "node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -101,9 +101,9 @@ } }, "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "dev": true }, "uuid": { diff --git a/JEU2/package.json b/srcs/requirements/game_server/game_back/package.json similarity index 88% rename from JEU2/package.json rename to srcs/requirements/game_server/game_back/package.json index f8f23534..b9702186 100644 --- a/JEU2/package.json +++ b/srcs/requirements/game_server/game_back/package.json @@ -4,7 +4,7 @@ "@types/node": "^18.11.5", "@types/uuid": "^8.3.4", "@types/ws": "^8.5.3", - "typescript": "^4.8.4" + "typescript": "^4.9.4" }, "dependencies": { "uuid": "^9.0.0", diff --git a/JEU2/src/server/class/Client.ts b/srcs/requirements/game_server/game_back/src/server/class/Client.ts similarity index 69% rename from JEU2/src/server/class/Client.ts rename to srcs/requirements/game_server/game_back/src/server/class/Client.ts index dead987b..864472ec 100644 --- a/JEU2/src/server/class/Client.ts +++ b/srcs/requirements/game_server/game_back/src/server/class/Client.ts @@ -2,22 +2,24 @@ import { WebSocket } from "../wsServer.js"; import { Racket } from "../../shared_js/class/Rectangle.js"; import { GameSession } from "./GameSession.js"; -import * as ev from "./Event.js" -import * as en from "../enums.js" +import * as ev from "../../shared_js/class/Event.js" +import * as en from "../../shared_js/enums.js" -class Client { +export class Client { socket: WebSocket; - id: string; // Pas indispensable si "socket" a une copie de "id" + id: string; // same as "socket.id" isAlive: boolean = true; gameSession: GameSession = null; - matchOptions: en.MatchOptions = 0; constructor(socket: WebSocket, id: string) { this.socket = socket; this.id = id; } } -class ClientPlayer extends Client { +export class ClientPlayer extends Client { + token: string; + username: string; + matchOptions: en.MatchOptions = 0; inputBuffer: ev.EventInput = new ev.EventInput(); lastInputId: number = 0; racket: Racket; @@ -27,10 +29,8 @@ class ClientPlayer extends Client { } } -class ClientSpectator extends Client { // Wip, unused +export class ClientSpectator extends Client { constructor(socket: WebSocket, id: string) { super(socket, id); } } - -export {Client, ClientPlayer, ClientSpectator} diff --git a/JEU2/src/server/class/GameComponentsServer.ts b/srcs/requirements/game_server/game_back/src/server/class/GameComponentsServer.ts similarity index 55% rename from JEU2/src/server/class/GameComponentsServer.ts rename to srcs/requirements/game_server/game_back/src/server/class/GameComponentsServer.ts index d05858e7..691a3991 100644 --- a/JEU2/src/server/class/GameComponentsServer.ts +++ b/srcs/requirements/game_server/game_back/src/server/class/GameComponentsServer.ts @@ -1,9 +1,8 @@ -import * as c from "../constants.js" -import * as en from "../enums.js" +import * as en from "../../shared_js/enums.js" import { GameComponents } from "../../shared_js/class/GameComponents.js"; -class GameComponentsServer extends GameComponents { +export class GameComponentsServer extends GameComponents { scoreLeft: number = 0; scoreRight: number = 0; constructor(options: en.MatchOptions) @@ -11,5 +10,3 @@ class GameComponentsServer extends GameComponents { super(options); } } - -export {GameComponentsServer} diff --git a/srcs/requirements/game_server/game_back/src/server/class/GameSession.ts b/srcs/requirements/game_server/game_back/src/server/class/GameSession.ts new file mode 100644 index 00000000..24988b86 --- /dev/null +++ b/srcs/requirements/game_server/game_back/src/server/class/GameSession.ts @@ -0,0 +1,302 @@ + +import * as en from "../../shared_js/enums.js" +import * as ev from "../../shared_js/class/Event.js" +import * as c from "../constants.js" +import { ClientPlayer, ClientSpectator } from "./Client"; +import { GameComponentsServer } from "./GameComponentsServer.js"; +import { clientInputListener, clientTerminate } from "../wsServer.js"; +import { random } from "../utils.js"; +import { Ball } from "../../shared_js/class/Rectangle.js"; +import { wallsMovements } from "../../shared_js/wallsMovement.js"; + +/* + multiples methods of GameSession have parameter "s: GameSession". + its used with calls to setTimeout(), + because "this" is not equal to the GameSession but to "this: Timeout" +*/ +export class GameSession { + id: string; // url ? + playersMap: Map = new Map(); + unreadyPlayersMap: Map = new Map(); + spectatorsMap: Map = new Map(); + gameLoopInterval: NodeJS.Timer | number = 0; + playersUpdateInterval: NodeJS.Timer | number = 0; + spectatorsUpdateInterval: NodeJS.Timer | number = 0; + components: GameComponentsServer; + matchOptions: en.MatchOptions; + isPrivateMatch: boolean; // WIP: could be used to separate leaderboards for example. + matchEnded: boolean = false; + lastStateSnapshot: ev.EventGameUpdate; + + actual_time: number; + last_time: number; + delta_time: number; + + constructor(id: string, matchOptions: en.MatchOptions, isPrivateMatch: boolean = false) { + this.id = id; + this.matchOptions = matchOptions; + this.isPrivateMatch = isPrivateMatch; + this.components = new GameComponentsServer(this.matchOptions); + } + start() { + const gc = this.components; + setTimeout(this.resume, c.matchStartDelay, this); + + let timeout = c.matchStartDelay + c.newRoundDelay; + gc.ballsArr.forEach((ball) => { + setTimeout(this._newRound, timeout, this, ball); + timeout += c.newRoundDelay*0.5; + }); + } + resume(s?: GameSession) + { + if (!s) { s = this; } + + s.playersMap.forEach( (client) => { + client.socket.on("message", clientInputListener); + }); + + s.actual_time = Date.now(); + s.lastStateSnapshot = s._gameStateSnapshot(); + s.gameLoopInterval = setInterval(s._gameLoop, c.serverGameLoopIntervalMS, s); + s.playersUpdateInterval = setInterval(s._playersUpdate, c.playersUpdateIntervalMS, s); + s.spectatorsUpdateInterval = setInterval(s._spectatorsUpdate, c.spectatorsUpdateIntervalMS, s); + } + pause(s?: GameSession) + { + if (!s) { s = this; } + + s.playersMap.forEach( (client) => { + client.socket.off("message", clientInputListener); + }); + + clearInterval(s.gameLoopInterval); + clearInterval(s.playersUpdateInterval); + clearInterval(s.spectatorsUpdateInterval); + } + destroy(s?: GameSession) + { + if (!s) { s = this; } + + s.pause(); + + s.spectatorsMap.forEach((client) => { + clientTerminate(client); + }); + s.playersMap.forEach((client) => { + clientTerminate(client); + }); + } + instantInputDebug(client: ClientPlayer) { + this._handleInput(c.fixedDeltaTime, client); + } + private _handleInput(delta: number, client: ClientPlayer) { + // if (client.inputBuffer === null) {return;} + const gc = this.components; + const input = client.inputBuffer.input; + + if (input === en.InputEnum.up) { + client.racket.dir.y = -1; + } + else if (input === en.InputEnum.down) { + client.racket.dir.y = 1; + } + + if (input !== en.InputEnum.noInput) { + client.racket.moveAndCollide(delta, [gc.wallTop, gc.wallBottom]); + } + + client.lastInputId = client.inputBuffer.id; + // client.inputBuffer = null; + } + private _gameLoop(s: GameSession) { + /* s.last_time = s.actual_time; + s.actual_time = Date.now(); + s.delta_time = (s.actual_time - s.last_time) / 1000; */ + s.delta_time = c.fixedDeltaTime; + + // WIP, replaced by instantInputDebug() to prevent desynchro + /* s.playersMap.forEach( (client) => { + s._handleInput(s.delta_time, client); + }); */ + + const gc = s.components; + gc.ballsArr.forEach((ball) => { + s._ballMovement(s.delta_time, ball); + }); + + if (s.matchOptions & en.MatchOptions.movingWalls) { + wallsMovements(s.delta_time, gc); + } + } + private _ballMovement(delta: number, ball: Ball) { + const gc = this.components; + if (ball.ballInPlay) + { + ball.moveAndBounce(delta, [gc.wallTop, gc.wallBottom, gc.playerLeft, gc.playerRight]); + if (ball.pos.x > c.w + || ball.pos.x < 0 - ball.width) + { + ball.ballInPlay = false; + if (this.matchEnded) { + return; + } + this._scoreUpdate(ball); + setTimeout(this._newRound, c.newRoundDelay, this, ball); + } + } + } + private _scoreUpdate(ball: Ball) { + const gc = this.components; + if (ball.pos.x > c.w) { + ++gc.scoreLeft; + } + else if (ball.pos.x < 0 - ball.width) { + ++gc.scoreRight; + } + const scoreUpdate = new ev.EventScoreUpdate(gc.scoreLeft, gc.scoreRight); + this.playersMap.forEach( (client) => { + client.socket.send(JSON.stringify(scoreUpdate)); + }); + this.spectatorsMap.forEach( (client) => { + client.socket.send(JSON.stringify(scoreUpdate)); + }); + } + private _playersUpdate(s: GameSession) { + s.lastStateSnapshot = s._gameStateSnapshot(); + s.playersMap.forEach( (client) => { + s.lastStateSnapshot.lastInputId = client.lastInputId; + client.socket.send(JSON.stringify(s.lastStateSnapshot)); + }); + s.lastStateSnapshot.lastInputId = 0; + } + private _spectatorsUpdate(s: GameSession) { + s.spectatorsMap.forEach( (client) => { + client.socket.send(JSON.stringify(s.lastStateSnapshot)); + }); + } + private _gameStateSnapshot() : ev.EventGameUpdate { + const gc = this.components; + const snapshot = new ev.EventGameUpdate(); + snapshot.playerLeft.y = gc.playerLeft.pos.y; + snapshot.playerRight.y = gc.playerRight.pos.y; + gc.ballsArr.forEach((ball) => { + snapshot.ballsArr.push({ + x: ball.pos.x, + y: ball.pos.y, + dirX: ball.dir.x, + dirY: ball.dir.y, + speed: ball.speed + }); + }); + if (this.matchOptions & en.MatchOptions.movingWalls) { + snapshot.wallTop.y = gc.wallTop.pos.y; + snapshot.wallBottom.y = gc.wallBottom.pos.y; + } + return (snapshot); + } + private _newRound(s: GameSession, ball: Ball) { + if (s._checkDisconnexions()) { + return; + } + // https://fr.wikipedia.org/wiki/Tennis_de_table#Nombre_de_manches + const gc = s.components; + const minScore = 11;// can be changed for testing + if (gc.scoreLeft >= minScore || gc.scoreRight >= minScore) + { + if (Math.abs(gc.scoreLeft - gc.scoreRight) >= 2) + { + if (gc.scoreLeft > gc.scoreRight) { + s._matchEnd(en.PlayerSide.left); + } + else { + s._matchEnd(en.PlayerSide.right); + } + return; + } + } + ball.pos.x = c.w_mid; + ball.pos.y = random(c.h*0.3, c.h*0.7); + ball.speed = ball.baseSpeed; + ball.ballInPlay = true; + } + private _checkDisconnexions() + { + if (this.playersMap.size !== 2) + { + this.matchEnded = true; + if (this.playersMap.size != 0) { + this._forfeit(); + } + else { + // WIP: envoyer un truc à Nest ? Genre "match draw" + this.destroy(); + } + return true; + } + return false; + } + private _forfeit() + { + this.matchEnded = true; + console.log("Forfeit Ending"); + const gc = this.components; + const luckyWinner: ClientPlayer = this.playersMap.values().next().value; + if (luckyWinner.racket === gc.playerLeft) { + this._matchEnd(en.PlayerSide.left, true); + } + else { + this._matchEnd(en.PlayerSide.right, true); + } + } + + private async _matchEnd(winner: en.PlayerSide, forfeit_flag: boolean = false) + { + this.matchEnded = true; + const eventEnd = new ev.EventMatchEnd(winner, forfeit_flag); + this.playersMap.forEach( (client) => { + client.socket.send(JSON.stringify(eventEnd)); + }); + this.spectatorsMap.forEach( (client) => { + client.socket.send(JSON.stringify(eventEnd)); + }); + + // TODO: mettre à jour la route pour gerer les forfaits (actuellement le plus haut score gagne par defaut) + const gc = this.components; + console.log("================================= MATCH ENDED"); + if (forfeit_flag) { + if (winner === en.PlayerSide.left) + { + gc.scoreLeft = 3 + gc.scoreRight = 0 + } + else + { + gc.scoreLeft = 0 + gc.scoreRight = 3 + } + } + await fetch(c.addressBackEnd + "/game/gameserver/updategame", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + gameServerIdOfTheMatch: this.id, + playerOneUsernameResult: gc.scoreLeft, + playerTwoUsernameResult: gc.scoreRight, + }) + }); + + setTimeout(this.destroy, 15000, this); + + // logs + if (winner === en.PlayerSide.left) { + console.log("Player Left WIN"); + } + else { + console.log("Player Right WIN"); + } + } +} diff --git a/srcs/requirements/game_server/game_back/src/server/constants.ts b/srcs/requirements/game_server/game_back/src/server/constants.ts new file mode 100644 index 00000000..3ae3e722 --- /dev/null +++ b/srcs/requirements/game_server/game_back/src/server/constants.ts @@ -0,0 +1,12 @@ + +export * from "../shared_js/constants.js" + +// 15ms == 1000/66.666 +export const serverGameLoopIntervalMS = 15; // millisecond +export const fixedDeltaTime = serverGameLoopIntervalMS/1000; // second + +// 33.333ms == 1000/30 +export const playersUpdateIntervalMS = 1000/30; // millisecond +export const spectatorsUpdateIntervalMS = 1000/30; // millisecond + +export const addressBackEnd = "http://backend_dev:3000/api/v2"; diff --git a/srcs/requirements/game_server/game_back/src/server/utils.ts b/srcs/requirements/game_server/game_back/src/server/utils.ts new file mode 100644 index 00000000..3cd0a4a5 --- /dev/null +++ b/srcs/requirements/game_server/game_back/src/server/utils.ts @@ -0,0 +1,6 @@ + +export * from "../shared_js/utils.js" + +export function shortId(id: string): string { + return id.substring(0, id.indexOf("-")); +} diff --git a/srcs/requirements/game_server/game_back/src/server/wsServer.ts b/srcs/requirements/game_server/game_back/src/server/wsServer.ts new file mode 100644 index 00000000..99fc6597 --- /dev/null +++ b/srcs/requirements/game_server/game_back/src/server/wsServer.ts @@ -0,0 +1,426 @@ + +import { WebSocketServer, WebSocket as BaseLibWebSocket } from "ws"; + +export class WebSocket extends BaseLibWebSocket { + id?: string; +} + +import { IncomingMessage } from "http"; +import { v4 as uuidv4 } from 'uuid'; + +import * as en from "../shared_js/enums.js" +import * as ev from "../shared_js/class/Event.js" +import * as c from "./constants.js" +import { Client, ClientPlayer, ClientSpectator } from "./class/Client.js" +import { GameSession } from "./class/GameSession.js" +import { shortId } from "./utils.js"; + +const wsPort = 8042; +export const wsServer = new WebSocketServer({host: "0.0.0.0", port: wsPort, path: "/pong"}); +const clientsMap: Map = new Map; // socket.id/Client +const matchmakingMap: Map = new Map; // socket.id/ClientPlayer (duplicates with clientsMap) +const privateMatchmakingMap: Map = new Map; // socket.id/ClientPlayer (duplicates with clientsMap) +const gameSessionsMap: Map = new Map; // GameSession.id(url)/GameSession + +wsServer.on("connection", serverConnectionListener); +wsServer.on("error", serverErrorListener); +wsServer.on("close", serverCloseListener); + + +function serverConnectionListener(socket: WebSocket, request: IncomingMessage) +{ + const id = uuidv4(); + const client = new Client(socket, id); + clientsMap.set(id, client); + socket.id = id; + + socket.on("pong", function heartbeat() { + client.isAlive = true; + console.log(`client ${shortId(client.id)} is alive`); + }); + + socket.on("close", function removeClient() { + clientTerminate(client); + }); + + socket.on("error", function errorLog(this: WebSocket, err: Error) { + console.log(`error socket ${shortId(this.id)}:`); + console.log(`${err.name}: ${err.message}`); + if (err.stack) { + console.log(`err.stack: ${err.stack}`); + } + }); + + socket.on("message", function messageLog(data: string) { + try { + const event: ev.ClientEvent = JSON.parse(data); + if (event.type === en.EventTypes.clientInput) { + return; + } + } + catch (e) {} + console.log("data: " + data); + }); + + socket.once("message", clientAnnounceListener); +} + + +async function clientAnnounceListener(this: WebSocket, data: string) +{ + try { + const msg : ev.ClientAnnounce = JSON.parse(data); + if (msg.type === en.EventTypes.clientAnnounce) + { + // BONUS: reconnection with msg.clientId ? + if (msg.role === en.ClientRole.player) + { + const announce: ev.ClientAnnouncePlayer = msg; + + const body = { + playerOneUsername: announce.username, + playerTwoUsername: "", + gameOptions: announce.matchOptions, + isGameIsWithInvitation: announce.privateMatch, + token: announce.token, + }; + if (announce.privateMatch) { + body.playerTwoUsername = announce.playerTwoUsername; + } + const response = await fetch(c.addressBackEnd + "/game/gameserver/validate", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body) + }); + if (!response.ok) + { + this.send(JSON.stringify( new ev.EventError((await response.json()).message) )); + clientTerminate(clientsMap.get(this.id)); + return; + } + + const player = clientsMap.get(this.id) as ClientPlayer; + player.matchOptions = announce.matchOptions; + player.token = announce.token; + player.username = announce.username; + this.send(JSON.stringify( new ev.EventAssignId(this.id) )); // unused + this.send(JSON.stringify( new ev.ServerEvent(en.EventTypes.matchmakingInProgress) )); + if (announce.privateMatch) { + if (announce.isInvitedPerson) { + player.username = announce.playerTwoUsername; + } + privateMatchmaking(player); + } + else { + publicMatchmaking(player); + } + } + else if (msg.role === en.ClientRole.spectator) + { + const announce: ev.ClientAnnounceSpectator = msg; + const gameSession = gameSessionsMap.get(announce.gameSessionId); + if (!gameSession) { + this.send(JSON.stringify( new ev.EventError("invalid gameSessionId") )); + clientTerminate(clientsMap.get(this.id)); + return; + } + const spectator = clientsMap.get(this.id) as ClientSpectator; + spectator.gameSession = gameSession; + gameSession.spectatorsMap.set(spectator.id, spectator); + spectator.socket.once("message", spectatorReadyConfirmationListener); + this.send(JSON.stringify( new ev.ServerEvent(en.EventTypes.matchStart) )); + } + } + else { + console.log("Invalid ClientAnnounce"); + } + return; + } + catch (e) { + console.log("Invalid JSON (clientAnnounceListener)"); + } + this.once("message", clientAnnounceListener); +} + + +function publicMatchmaking(player: ClientPlayer) +{ + const minPlayersNumber = 2; + const maxPlayersNumber = 2; + matchmakingMap.set(player.id, player); + const matchOptions = player.matchOptions; + + const compatiblePlayers: ClientPlayer[] = []; + for (const [id, client] of matchmakingMap) + { + if (client.matchOptions === matchOptions) + { + compatiblePlayers.push(client); + if (compatiblePlayers.length === maxPlayersNumber) { + break; + } + } + } + + if (compatiblePlayers.length >= minPlayersNumber) { + compatiblePlayers.forEach((client) => { + matchmakingMap.delete(client.id); + }); + createGameSession(compatiblePlayers, matchOptions); + } +} + + +function privateMatchmaking(player: ClientPlayer) +{ + const minPlayersNumber = 2; + const maxPlayersNumber = 2; + privateMatchmakingMap.set(player.id, player); + const matchOptions = player.matchOptions; + + const token = player.token; + const compatiblePlayers: ClientPlayer[] = []; + for (const [id, client] of privateMatchmakingMap) + { + if (client.token === token) + { + compatiblePlayers.push(client); + if (compatiblePlayers.length === maxPlayersNumber) { + break; + } + } + } + + if (compatiblePlayers.length >= minPlayersNumber) { + compatiblePlayers.forEach((client) => { + privateMatchmakingMap.delete(client.id); + }); + createGameSession(compatiblePlayers, matchOptions); + } + else + { + setTimeout(async function abortMatch() { + if (!player.gameSession) + { + if (player.socket.OPEN) { + player.socket.send(JSON.stringify( new ev.EventMatchAbort() )); + } + const response = await fetch(c.addressBackEnd + "/game/gameserver/destroysession",{ + method: "POST", + headers : {"Content-Type": "application/json"}, + body : JSON.stringify({ + token : player.token + }) + }) + .then(x => x.json()) + .catch(error => console.log("ERROR : " + error)); + clientTerminate(player); + } + }, 60000); + } +} + + +function createGameSession(playersArr: ClientPlayer[], matchOptions: en.MatchOptions) +{ + // const id = c.gameSessionIdPLACEHOLDER; // Force ID, TESTING SPECTATOR + const id = uuidv4(); + const gameSession = new GameSession(id, matchOptions); + gameSessionsMap.set(id, gameSession); + + playersArr.forEach((client) => { + client.gameSession = gameSession; + gameSession.playersMap.set(client.id, client); + gameSession.unreadyPlayersMap.set(client.id, client); + client.socket.once("message", playerReadyConfirmationListener); + }); + + // REFACTORING: Not pretty, hardcoded two players. + // Could be done in gameSession maybe ? + const gameSessionPlayersIterator = gameSession.playersMap.values(); + let player: ClientPlayer; + player = (gameSessionPlayersIterator.next().value); + player.racket = gameSession.components.playerLeft; + player.socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.left) )); + + player = (gameSessionPlayersIterator.next().value); + player.racket = gameSession.components.playerRight; + player.socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.right) )); + // REFACTORING + + setTimeout(function abortMatch() { + if (gameSession.unreadyPlayersMap.size !== 0) + { + gameSessionsMap.delete(gameSession.id); + gameSession.playersMap.forEach((client) => { + client.socket.send(JSON.stringify( new ev.EventMatchAbort() )); + client.gameSession = null; + clientTerminate(client); + }); + } + }, 5000); +} + + +async function playerReadyConfirmationListener(this: WebSocket, data: string) +{ + try { + const msg : ev.ClientEvent = JSON.parse(data); + if (msg.type === en.EventTypes.clientPlayerReady) + { + const client = clientsMap.get(this.id); + const gameSession = client.gameSession; + gameSession.unreadyPlayersMap.delete(this.id); + if (gameSession.unreadyPlayersMap.size === 0) + { + const gameSessionPlayersIterator = gameSession.playersMap.values(); + const body = { + gameServerIdOfTheMatch : gameSession.id, + gameOptions: gameSession.matchOptions, + playerOneUsername: (gameSessionPlayersIterator.next().value).username, + playerTwoUsername: (gameSessionPlayersIterator.next().value).username, + playerOneUsernameResult : 0, + playerTwoUsernameResult : 0 + }; + const response = await fetch(c.addressBackEnd + "/game/gameserver/creategame", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body) + }); + if (!response.ok) + { + gameSessionsMap.delete(gameSession.id); + gameSession.playersMap.forEach((client) => { + client.socket.send(JSON.stringify( new ev.EventMatchAbort() )); + client.gameSession = null; + clientTerminate(client); + }); + return; + } + + gameSession.playersMap.forEach( (client) => { + client.socket.send(JSON.stringify( new ev.ServerEvent(en.EventTypes.matchStart) )); + }); + gameSession.start(); + } + } + else { + console.log("Invalid playerReadyConfirmation"); + } + return; + } + catch (e) { + console.log("Invalid JSON (playerReadyConfirmationListener)"); + } + this.once("message", playerReadyConfirmationListener); +} + + +export function clientInputListener(this: WebSocket, data: string) +{ + try { + // const input: ev.ClientEvent = JSON.parse(data); + const input: ev.EventInput = JSON.parse(data); + if (input.type === en.EventTypes.clientInput) + { + const client = clientsMap.get(this.id) as ClientPlayer; + client.inputBuffer = input; + client.gameSession.instantInputDebug(client); // wip + } + else { + console.log("Invalid clientInput"); + } + } + catch (e) { + console.log("Invalid JSON (clientInputListener)"); + } +} + +function spectatorReadyConfirmationListener(this: WebSocket, data: string) +{ + try { + const msg : ev.ClientEvent = JSON.parse(data); + if (msg.type === en.EventTypes.clientSpectatorReady) + { + const client = clientsMap.get(this.id); + const gameSession = client.gameSession; + const scoreUpdate = new ev.EventScoreUpdate(gameSession.components.scoreLeft, gameSession.components.scoreRight); + this.send(JSON.stringify(scoreUpdate)); + } + else { + console.log("Invalid spectatorReadyConfirmation"); + } + return; + } + catch (e) { + console.log("Invalid JSON (spectatorReadyConfirmationListener)"); + } + this.once("message", spectatorReadyConfirmationListener); +} + +//////////// +//////////// + +const pingInterval = setInterval( () => { + let deleteLog = ""; + clientsMap.forEach( (client) => { + if (!client.isAlive) { + clientTerminate(client); + deleteLog += ` ${shortId(client.id)} |`; + } + else { + client.isAlive = false; + client.socket.ping(); + } + }); + + if (deleteLog) { + console.log(`Disconnected:${deleteLog}`); + } + console.log("gameSessionMap size: " + gameSessionsMap.size); + console.log("clientsMap size: " + clientsMap.size); + console.log("matchmakingMap size: " + matchmakingMap.size); + console.log("privateMatchmakingMap size: " + privateMatchmakingMap.size); + console.log(""); +}, 4200); + + +export function clientTerminate(client: Client) +{ + client.socket.terminate(); + if (client.gameSession) + { + client.gameSession.playersMap.delete(client.id); + client.gameSession.spectatorsMap.delete(client.id); + if (client.gameSession.playersMap.size === 0) + { + client.gameSession.destroy(); + gameSessionsMap.delete(client.gameSession.id); + } + } + clientsMap.delete(client.id); + if (matchmakingMap.has(client.id)) { + matchmakingMap.delete(client.id); + } + else if (privateMatchmakingMap.has(client.id)) { + privateMatchmakingMap.delete(client.id); + } +} + + +function serverCloseListener() +{ + clearInterval(pingInterval); +} + + +function serverErrorListener(error: Error) +{ + console.log("Error: " + JSON.stringify(error)); +} diff --git a/srcs/requirements/game_server/game_back/src/shared_js/class/Event.ts b/srcs/requirements/game_server/game_back/src/shared_js/class/Event.ts new file mode 100644 index 00000000..0147ead8 --- /dev/null +++ b/srcs/requirements/game_server/game_back/src/shared_js/class/Event.ts @@ -0,0 +1,144 @@ + +import * as en from "../enums.js" + +/* From Server */ +export class ServerEvent { + type: en.EventTypes; + constructor(type: en.EventTypes = 0) { + this.type = type; + } +} + +export class EventAssignId extends ServerEvent { + id: string; + constructor(id: string) { + super(en.EventTypes.assignId); + this.id = id; + } +} + +export class EventMatchmakingComplete extends ServerEvent { + side: en.PlayerSide; + constructor(side: en.PlayerSide) { + super(en.EventTypes.matchmakingComplete); + this.side = side; + } +} + +export class EventGameUpdate extends ServerEvent { + playerLeft = { + y: 0 + }; + playerRight = { + y: 0 + }; + ballsArr: { + x: number, + y: number, + dirX: number, + dirY: number, + speed: number + }[] = []; + wallTop? = { + y: 0 + }; + wallBottom? = { + y: 0 + }; + lastInputId = 0; + constructor() { // TODO: constructor that take GameComponentsServer maybe ? + super(en.EventTypes.gameUpdate); + } +} + +export class EventScoreUpdate extends ServerEvent { + scoreLeft: number; + scoreRight: number; + constructor(scoreLeft: number, scoreRight: number) { + super(en.EventTypes.scoreUpdate); + this.scoreLeft = scoreLeft; + this.scoreRight = scoreRight; + } +} + +export class EventMatchEnd extends ServerEvent { + winner: en.PlayerSide; + forfeit: boolean; + constructor(winner: en.PlayerSide, forfeit = false) { + super(en.EventTypes.matchEnd); + this.winner = winner; + this.forfeit = forfeit; + } +} + +export class EventMatchAbort extends ServerEvent { + constructor() { + super(en.EventTypes.matchAbort); + } +} + +export class EventError extends ServerEvent { + message: string; + constructor(message: string) { + super(en.EventTypes.error); + this.message = message; + } +} + + +/* From Client */ +export class ClientEvent { + type: en.EventTypes; // readonly ? + constructor(type: en.EventTypes = 0) { + this.type = type; + } +} + +export class ClientAnnounce extends ClientEvent { + role: en.ClientRole; + constructor(role: en.ClientRole) { + super(en.EventTypes.clientAnnounce); + this.role = role; + } +} + +export class ClientAnnouncePlayer extends ClientAnnounce { + clientId: string; // unused + matchOptions: en.MatchOptions; + token: string; + username: string; + privateMatch: boolean; + playerTwoUsername?: string; + isInvitedPerson? : boolean; + constructor(matchOptions: en.MatchOptions, token: string, username: string, privateMatch: boolean = false, playerTwoUsername?: string, isInvitedPerson? : boolean) { + super(en.ClientRole.player); + this.matchOptions = matchOptions; + this.token = token; + this.username = username; + this.privateMatch = privateMatch; + if (isInvitedPerson) { + this.isInvitedPerson = isInvitedPerson; + } + if (playerTwoUsername) { + this.playerTwoUsername = playerTwoUsername; + } + } +} + +export class ClientAnnounceSpectator extends ClientAnnounce { + gameSessionId: string; + constructor(gameSessionId: string) { + super(en.ClientRole.spectator); + this.gameSessionId = gameSessionId; + } +} + +export class EventInput extends ClientEvent { + input: en.InputEnum; + id: number; + constructor(input: en.InputEnum = en.InputEnum.noInput, id: number = 0) { + super(en.EventTypes.clientInput); + this.input = input; + this.id = id; + } +} diff --git a/srcs/requirements/svelte/api_front/public/game/class/GameComponents.ts b/srcs/requirements/game_server/game_back/src/shared_js/class/GameComponents.ts similarity index 97% rename from srcs/requirements/svelte/api_front/public/game/class/GameComponents.ts rename to srcs/requirements/game_server/game_back/src/shared_js/class/GameComponents.ts index 10e60932..ec36f15f 100644 --- a/srcs/requirements/svelte/api_front/public/game/class/GameComponents.ts +++ b/srcs/requirements/game_server/game_back/src/shared_js/class/GameComponents.ts @@ -5,7 +5,7 @@ import { VectorInteger } from "./Vector.js"; import { Rectangle, MovingRectangle, Racket, Ball } from "./Rectangle.js"; import { random } from "../utils.js"; -class GameComponents { +export class GameComponents { wallTop: Rectangle | MovingRectangle; wallBottom: Rectangle | MovingRectangle; playerLeft: Racket; @@ -61,5 +61,3 @@ class GameComponents { } } } - -export {GameComponents} diff --git a/srcs/requirements/svelte/api_front/public/game/class/Rectangle.ts b/srcs/requirements/game_server/game_back/src/shared_js/class/Rectangle.ts similarity index 93% rename from srcs/requirements/svelte/api_front/public/game/class/Rectangle.ts rename to srcs/requirements/game_server/game_back/src/shared_js/class/Rectangle.ts index fff71dc9..d258c553 100644 --- a/srcs/requirements/svelte/api_front/public/game/class/Rectangle.ts +++ b/srcs/requirements/game_server/game_back/src/shared_js/class/Rectangle.ts @@ -1,9 +1,9 @@ import { Vector, VectorInteger } from "./Vector.js"; -import { Component, Moving } from "./interface.js"; +import type { Component, Moving } from "./interface.js"; import * as c from "../constants.js" -class Rectangle implements Component { +export class Rectangle implements Component { pos: VectorInteger; width: number; height: number; @@ -33,7 +33,7 @@ class Rectangle implements Component { } } -class MovingRectangle extends Rectangle implements Moving { +export class MovingRectangle extends Rectangle implements Moving { dir: Vector = new Vector(0,0); speed: number; readonly baseSpeed: number; @@ -61,7 +61,7 @@ class MovingRectangle extends Rectangle implements Moving { } } -class Racket extends MovingRectangle { +export class Racket extends MovingRectangle { constructor(pos: VectorInteger, width: number, height: number, baseSpeed: number) { super(pos, width, height, baseSpeed); } @@ -72,13 +72,22 @@ class Racket extends MovingRectangle { } } -class Ball extends MovingRectangle { +export class Ball extends MovingRectangle { readonly speedIncrease: number; ballInPlay: boolean = false; constructor(pos: VectorInteger, size: number, baseSpeed: number, speedIncrease: number) { super(pos, size, size, baseSpeed); this.speedIncrease = speedIncrease; } + moveAndBounce(delta: number, colliderArr: Rectangle[]) { + this.move(delta); + let i = colliderArr.findIndex(this.collision, this); + if (i != -1) + { + this.bounce(colliderArr[i]); + this.move(delta); + } + } bounce(collider?: Rectangle) { this._bounceAlgo(collider); } @@ -92,15 +101,6 @@ class Ball extends MovingRectangle { this._bounceWall(); } } - moveAndBounce(delta: number, colliderArr: Rectangle[]) { - this.move(delta); - let i = colliderArr.findIndex(this.collision, this); - if (i != -1) - { - this.bounce(colliderArr[i]); - this.move(delta); - } - } protected _bounceWall() { // Should be enough for Wall this.dir.y = this.dir.y * -1; } @@ -140,5 +140,3 @@ class Ball extends MovingRectangle { // console.log(`x: ${this.dir.x}, y: ${this.dir.y}`); } } - -export {Rectangle, MovingRectangle, Racket, Ball} diff --git a/srcs/requirements/svelte/api_front/public/game/class/Vector.ts b/srcs/requirements/game_server/game_back/src/shared_js/class/Vector.ts similarity index 88% rename from srcs/requirements/svelte/api_front/public/game/class/Vector.ts rename to srcs/requirements/game_server/game_back/src/shared_js/class/Vector.ts index 025bca36..fbe121e5 100644 --- a/srcs/requirements/svelte/api_front/public/game/class/Vector.ts +++ b/srcs/requirements/game_server/game_back/src/shared_js/class/Vector.ts @@ -1,5 +1,5 @@ -class Vector { +export class Vector { x: number; y: number; constructor(x: number = 0, y: number = 0) { @@ -16,13 +16,13 @@ class Vector { } } -class VectorInteger extends Vector { +export class VectorInteger extends Vector { // PLACEHOLDER // VectorInteger with set/get dont work (No draw on the screen). Why ? } /* -class VectorInteger { +export class VectorInteger { // private _x: number = 0; // private _y: number = 0; // constructor(x: number = 0, y: number = 0) { @@ -45,5 +45,3 @@ class VectorInteger { // } } */ - -export {Vector, VectorInteger} diff --git a/srcs/requirements/svelte/api_front/public/game/class/interface.ts b/srcs/requirements/game_server/game_back/src/shared_js/class/interface.ts similarity index 53% rename from srcs/requirements/svelte/api_front/public/game/class/interface.ts rename to srcs/requirements/game_server/game_back/src/shared_js/class/interface.ts index 39753de1..0f484da3 100644 --- a/srcs/requirements/svelte/api_front/public/game/class/interface.ts +++ b/srcs/requirements/game_server/game_back/src/shared_js/class/interface.ts @@ -1,21 +1,19 @@ -import { Vector, VectorInteger } from "./Vector.js"; +import type { Vector, VectorInteger } from "./Vector.js"; -interface Component { +export interface Component { pos: VectorInteger; } -interface GraphicComponent extends Component { +export interface GraphicComponent extends Component { ctx: CanvasRenderingContext2D; color: string; update: () => void; clear: (pos?: VectorInteger) => void; } -interface Moving { +export interface Moving { dir: Vector; speed: number; // pixel per second move(delta: number): void; } - -export {Component, GraphicComponent, Moving} diff --git a/srcs/requirements/svelte/api_front/public/game/constants copy.ts b/srcs/requirements/game_server/game_back/src/shared_js/constants.ts similarity index 73% rename from srcs/requirements/svelte/api_front/public/game/constants copy.ts rename to srcs/requirements/game_server/game_back/src/shared_js/constants.ts index ae3320e5..18713ae4 100644 --- a/srcs/requirements/svelte/api_front/public/game/constants copy.ts +++ b/srcs/requirements/game_server/game_back/src/shared_js/constants.ts @@ -11,8 +11,8 @@ export const pw = Math.floor(w*0.017); export const ph = pw*6; export const ballSize = pw; export const wallSize = Math.floor(w*0.01); -export const racketSpeed = Math.floor(w*0.66); // pixel per second -export const ballSpeed = Math.floor(w*0.66); // pixel per second +export const racketSpeed = Math.floor(w*0.60); // pixel per second +export const ballSpeed = Math.floor(w*0.55); // pixel per second export const ballSpeedIncrease = Math.floor(ballSpeed*0.05); // pixel per second export const normalizedSpeed = false; // for consistency in speed independent of direction @@ -24,3 +24,7 @@ export const newRoundDelay = 1500; // millisecond export const multiBallsCount = 3; export const movingWallPosMax = Math.floor(w*0.12); export const movingWallSpeed = Math.floor(w*0.08); + + +export const gameSessionIdPLACEHOLDER = "match-id-test-42"; // TESTING SPECTATOR PLACEHOLDER +// for testing, force gameSession.id in wsServer.ts->createGameSession() diff --git a/srcs/requirements/svelte/api_front/public/game/enums.ts b/srcs/requirements/game_server/game_back/src/shared_js/enums.ts similarity index 73% rename from srcs/requirements/svelte/api_front/public/game/enums.ts rename to srcs/requirements/game_server/game_back/src/shared_js/enums.ts index dfba2aa3..6d54e139 100644 --- a/srcs/requirements/svelte/api_front/public/game/enums.ts +++ b/srcs/requirements/game_server/game_back/src/shared_js/enums.ts @@ -1,15 +1,17 @@ -enum EventTypes { +export enum EventTypes { // Class Implemented gameUpdate = 1, scoreUpdate, matchEnd, assignId, matchmakingComplete, + error, // Generic matchmakingInProgress, matchStart, + matchAbort, matchNewRound, // unused matchPause, // unused matchResume, // unused @@ -17,31 +19,30 @@ enum EventTypes { // Client clientAnnounce, clientPlayerReady, + clientSpectatorReady, clientInput, } -enum InputEnum { +export enum InputEnum { noInput = 0, up = 1, down, } -enum PlayerSide { +export enum PlayerSide { left = 1, right } -enum ClientRole { +export enum ClientRole { player = 1, spectator } -enum MatchOptions { +export enum MatchOptions { // binary flags, can be mixed noOption = 0b0, multiBalls = 1 << 0, movingWalls = 1 << 1 } - -export {EventTypes, InputEnum, PlayerSide, ClientRole, MatchOptions} diff --git a/srcs/requirements/game_server/game_back/src/shared_js/utils.ts b/srcs/requirements/game_server/game_back/src/shared_js/utils.ts new file mode 100644 index 00000000..dd3d40d0 --- /dev/null +++ b/srcs/requirements/game_server/game_back/src/shared_js/utils.ts @@ -0,0 +1,25 @@ + +import type { MovingRectangle } from "./class/Rectangle.js"; + +export function random(min: number = 0, max: number = 1) { + return Math.random() * (max - min) + min; +} + +export function sleep (ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +export function clamp(n: number, min: number, max: number) : number +{ + if (n < min) + n = min; + else if (n > max) + n = max; + return (n); +} + +// Typescript hack, unused +export function assertMovingRectangle(value: unknown): asserts value is MovingRectangle { + // if (value !== MovingRectangle) throw new Error("Not a MovingRectangle"); + return; +} diff --git a/JEU2/src/server/wallsMovement.ts b/srcs/requirements/game_server/game_back/src/shared_js/wallsMovement.ts similarity index 69% rename from JEU2/src/server/wallsMovement.ts rename to srcs/requirements/game_server/game_back/src/shared_js/wallsMovement.ts index dbf3f558..b2c2b581 100644 --- a/JEU2/src/server/wallsMovement.ts +++ b/srcs/requirements/game_server/game_back/src/shared_js/wallsMovement.ts @@ -1,9 +1,9 @@ import * as c from "./constants.js"; -import { MovingRectangle } from "../shared_js/class/Rectangle.js"; -import { GameComponents } from "./class/GameComponents.js"; +import type { MovingRectangle } from "../shared_js/class/Rectangle.js"; +import type { GameComponents } from "./class/GameComponents.js"; -function wallsMovements(delta: number, gc: GameComponents) +export function wallsMovements(delta: number, gc: GameComponents) { const wallTop = gc.wallTop; const wallBottom = gc.wallBottom; @@ -16,5 +16,3 @@ function wallsMovements(delta: number, gc: GameComponents) wallTop.moveAndCollide(delta, [gc.playerLeft, gc.playerRight]); wallBottom.moveAndCollide(delta, [gc.playerLeft, gc.playerRight]); } - -export {wallsMovements} diff --git a/srcs/requirements/game_server/game_back/tsconfig.json b/srcs/requirements/game_server/game_back/tsconfig.json new file mode 100644 index 00000000..9344b2b4 --- /dev/null +++ b/srcs/requirements/game_server/game_back/tsconfig.json @@ -0,0 +1,103 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "ES6", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + "strictNullChecks": false, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } + } diff --git a/srcs/requirements/nestjs/Dockerfile b/srcs/requirements/nestjs/Dockerfile index 7b7b7e7c..d4228c0b 100644 --- a/srcs/requirements/nestjs/Dockerfile +++ b/srcs/requirements/nestjs/Dockerfile @@ -3,10 +3,8 @@ FROM node:alpine AS development WORKDIR /usr/app COPY ./api_back ./ -COPY ./api_back/.env ./.env COPY ./api_back/src/uploads/avatars/default.png ./uploads/avatars/default.png -RUN npm ci - +RUN npm i CMD [ "npm", "run", "start:dev" ] diff --git a/srcs/requirements/nestjs/api_back/package-lock.json b/srcs/requirements/nestjs/api_back/package-lock.json index 9678a46f..c3e88cfb 100644 --- a/srcs/requirements/nestjs/api_back/package-lock.json +++ b/srcs/requirements/nestjs/api_back/package-lock.json @@ -12,13 +12,13 @@ "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0", - "@nestjs/jwt": "^9.0.0", "@nestjs/mapped-types": "^1.2.0", "@nestjs/passport": "^9.0.0", "@nestjs/platform-express": "^9.0.0", + "@nestjs/platform-socket.io": "^9.2.1", "@nestjs/typeorm": "^9.0.1", + "@nestjs/websockets": "^9.2.1", "@types/express-session": "^1.17.5", - "@types/redis": "^4.0.11", "@types/validator": "^13.7.9", "class-transformer": "^0.5.1", "class-validator": "^0.13.2", @@ -29,7 +29,6 @@ "otplib": "^12.0.1", "passport": "^0.6.0", "passport-42": "^1.2.6", - "passport-jwt": "^4.0.0", "passport-local": "^1.0.0", "pg": "^8.8.0", "qrcode": "^1.5.1", @@ -37,6 +36,7 @@ "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.2.0", + "socket.io": "^4.5.4", "typeorm": "^0.3.10", "uuid": "^9.0.0" }, @@ -47,8 +47,7 @@ "@types/express": "^4.17.13", "@types/jest": "28.1.8", "@types/multer": "^1.4.7", - "@types/node": "^16.0.0", - "@types/passport-jwt": "^3.0.7", + "@types/node": "^16.18.11", "@types/passport-local": "^1.0.34", "@types/supertest": "^2.0.11", "@typescript-eslint/eslint-plugin": "^5.0.0", @@ -237,30 +236,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.4.tgz", - "integrity": "sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.6.tgz", - "integrity": "sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", + "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.6", - "@babel/helper-compilation-targets": "^7.19.3", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helpers": "^7.19.4", - "@babel/parser": "^7.19.6", + "@babel/generator": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-module-transforms": "^7.20.2", + "@babel/helpers": "^7.20.5", + "@babel/parser": "^7.20.5", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.6", - "@babel/types": "^7.19.4", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -285,12 +284,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.6.tgz", - "integrity": "sha512-oHGRUQeoX1QrKeJIKVe0hwjGqNnVYsM5Nep5zo0uE0m42sLH+Fsd2pStJ5sRM1bNyTUUoz0pe2lTeMJrb/taTA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", "dev": true, "dependencies": { - "@babel/types": "^7.19.4", + "@babel/types": "^7.20.5", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -313,12 +312,12 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", - "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.19.3", + "@babel/compat-data": "^7.20.0", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", "semver": "^6.3.0" @@ -386,40 +385,40 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.6.tgz", - "integrity": "sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", + "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.19.4", + "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.6", - "@babel/types": "^7.19.4" + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", - "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", - "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "dev": true, "dependencies": { - "@babel/types": "^7.19.4" + "@babel/types": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -465,14 +464,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.4.tgz", - "integrity": "sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", "dev": true, "dependencies": { "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.4", - "@babel/types": "^7.19.4" + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" }, "engines": { "node": ">=6.9.0" @@ -564,9 +563,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.6.tgz", - "integrity": "sha512-h1IUp81s2JYJ3mRkdxJgs4UvmSsRvDrx5ICSJbPvtWYv5i1nTBGcBpnog+89rAFMwvvru6E5NUHdBe01UeSzYA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -723,12 +722,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", - "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -752,19 +751,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.6.tgz", - "integrity": "sha512-6l5HrUCzFM04mfbG09AagtYyR2P0B71B1wN7PfSPiksDPz2k5H9CBC1tcZpz2M8OxbKTPccByoOJ22rUKbpmQQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.6", + "@babel/generator": "^7.20.5", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.6", - "@babel/types": "^7.19.4", + "@babel/parser": "^7.20.5", + "@babel/types": "^7.20.5", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -782,9 +781,9 @@ } }, "node_modules/@babel/types": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", - "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.19.4", @@ -834,15 +833,15 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", + "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -879,14 +878,14 @@ "dev": true }, "node_modules/@humanwhocodes/config-array": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", - "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" @@ -911,6 +910,13 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", + "optional": true, + "peer": true + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1450,9 +1456,9 @@ } }, "node_modules/@nestjs/cli": { - "version": "9.1.4", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-9.1.4.tgz", - "integrity": "sha512-cvN4DcLzaqFzKRmpU3tOeLmw7+1p4XXsFLyWgteId0Szf6cAk5KJpD5jl2Kw7f39vNw9Pss8yiJ1q1CD/fcbwQ==", + "version": "9.1.5", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-9.1.5.tgz", + "integrity": "sha512-rSp26+Nv7PFtYrRSP18Gv5ZK8rRSc2SCCF5wh4SdZaVGgkxShpNq9YEfI+ik/uziN3KC5o74ppYRXGj+aHGVsA==", "dev": true, "dependencies": { "@angular-devkit/core": "14.2.2", @@ -1474,7 +1480,7 @@ "tree-kill": "1.2.2", "tsconfig-paths": "4.1.0", "tsconfig-paths-webpack-plugin": "4.0.0", - "typescript": "4.8.3", + "typescript": "4.8.4", "webpack": "5.74.0", "webpack-node-externals": "3.0.0" }, @@ -1486,9 +1492,9 @@ } }, "node_modules/@nestjs/cli/node_modules/typescript": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz", - "integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -1498,13 +1504,60 @@ "node": ">=4.2.0" } }, + "node_modules/@nestjs/cli/node_modules/webpack": { + "version": "5.74.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", + "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.10.0", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, "node_modules/@nestjs/common": { - "version": "9.1.4", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-9.1.4.tgz", - "integrity": "sha512-hmGTZ8ShKFDqqlU02uU8e/8PNE4bnES4pcFa6s/T1pLDYWjyf/75Klunro1W4aQPHcxnnohBmB27WxMqFTPEfw==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-9.2.1.tgz", + "integrity": "sha512-nZuo3oDsSSlC5mti/M2aCWTEIfHPGDXmBwWgPeCpRbrNz3IWd109rkajll+yxgidVjznAdBS9y00JkAVJblNYw==", "dependencies": { "iterare": "1.2.1", - "tslib": "2.4.0", + "tslib": "2.4.1", "uuid": "9.0.0" }, "funding": { @@ -1546,14 +1599,6 @@ "rxjs": "^6.0.0 || ^7.2.0" } }, - "node_modules/@nestjs/config/node_modules/dotenv": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz", - "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==", - "engines": { - "node": ">=12" - } - }, "node_modules/@nestjs/config/node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -1563,9 +1608,9 @@ } }, "node_modules/@nestjs/core": { - "version": "9.1.4", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-9.1.4.tgz", - "integrity": "sha512-S6KpGeKotPYh126hhRqYLhvg9lxSbAmGfEbK8m09crIK7CYP05t32KtT6n12xl5/iva1G4Ch87Z/3rYP76etUg==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-9.2.1.tgz", + "integrity": "sha512-a9GkXuu8uXgNgCVW+17iI8kLCltO+HwHpU2IhR+32JKnN2WEQ1YEWU4t3GJ2MNq44YkjIw9zrKvFkjJBlYrNbQ==", "hasInstallScript": true, "dependencies": { "@nuxtjs/opencollective": "0.3.2", @@ -1573,7 +1618,7 @@ "iterare": "1.2.1", "object-hash": "3.0.0", "path-to-regexp": "3.2.0", - "tslib": "2.4.0", + "tslib": "2.4.1", "uuid": "9.0.0" }, "funding": { @@ -1600,26 +1645,6 @@ } } }, - "node_modules/@nestjs/jwt": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-9.0.0.tgz", - "integrity": "sha512-ZsXGY/wMYKzEhymw2+dxiwrHTRKIKrGszx6r2EjQqNLypdXMQu0QrujwZJ8k3+XQV4snmuJwwNakQoA2ILfq8w==", - "dependencies": { - "@types/jsonwebtoken": "8.5.8", - "jsonwebtoken": "8.5.1" - }, - "peerDependencies": { - "@nestjs/common": "^8.0.0 || ^9.0.0" - } - }, - "node_modules/@nestjs/jwt/node_modules/@types/jsonwebtoken": { - "version": "8.5.8", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.8.tgz", - "integrity": "sha512-zm6xBQpFDIDM6o9r6HSgDeIcLy82TKWctCXEPbJJcXb5AKmi5BNNdLXneixK4lplX3PqIVcwLBCGE/kAGnlD4A==", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@nestjs/mapped-types": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-1.2.0.tgz", @@ -1649,15 +1674,15 @@ } }, "node_modules/@nestjs/platform-express": { - "version": "9.1.4", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-9.1.4.tgz", - "integrity": "sha512-SLJWDa6V54QrUvzKI4Eyt7gyrjV7F9FY1uHFihshjmQfpf0ebCGacR9jzNwf01aHl0BJX3DUn/KYteBjz6DJXw==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-9.2.1.tgz", + "integrity": "sha512-7PecaXt8lrdS1p6Vb1X/am3GGv+EO1VahyDzaEGOK6C0zwhc0VPfLtwihkjjfhS6BjpRIXXgviwEjONUvxVZnA==", "dependencies": { - "body-parser": "1.20.0", + "body-parser": "1.20.1", "cors": "2.8.5", - "express": "4.18.1", + "express": "4.18.2", "multer": "1.4.4-lts.1", - "tslib": "2.4.0" + "tslib": "2.4.1" }, "funding": { "type": "opencollective", @@ -1668,65 +1693,40 @@ "@nestjs/core": "^9.0.0" } }, - "node_modules/@nestjs/platform-express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/@nestjs/platform-socket.io": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/platform-socket.io/-/platform-socket.io-9.2.1.tgz", + "integrity": "sha512-McLXgmkNDvYhX4RcudpLa/RNvy7NA4vb+7gJxJ12yp189Ijcaoktrex1a4F7PPQ5iKACiI/D0rfvQAe9P1ez+g==", "dependencies": { - "ms": "2.0.0" + "socket.io": "4.5.3", + "tslib": "2.4.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "@nestjs/common": "^9.0.0", + "@nestjs/websockets": "^9.0.0", + "rxjs": "^7.1.0" } }, - "node_modules/@nestjs/platform-express/node_modules/express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "node_modules/@nestjs/platform-socket.io/node_modules/socket.io": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.3.tgz", + "integrity": "sha512-zdpnnKU+H6mOp7nYRXH4GNv1ux6HL6+lHL8g7Ds7Lj8CkdK1jJK/dlwsKDculbyOHifcJ0Pr/yeXnZQ5GeFrcg==", "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.0", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.10.3", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.2.0", + "socket.io-adapter": "~2.4.0", + "socket.io-parser": "~4.2.0" }, "engines": { - "node": ">= 0.10.0" + "node": ">=10.0.0" } }, - "node_modules/@nestjs/platform-express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/@nestjs/platform-express/node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, "node_modules/@nestjs/schematics": { "version": "9.0.3", "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-9.0.3.tgz", @@ -1824,12 +1824,12 @@ "dev": true }, "node_modules/@nestjs/testing": { - "version": "9.1.4", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-9.1.4.tgz", - "integrity": "sha512-gO6b9QJyUajh38DNdss9gSE0UO7x60Jh10W4SwHEjQT1W+yxaEWr3aLyuQItTvUVY6C28XKFLTykMpr8GO28Ug==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-9.2.1.tgz", + "integrity": "sha512-lemXZdRSuqoZ87l0orCrS/c7gqwxeduIFOd21g9g2RUeQ4qlWPegbQDKASzbfC28klPyrgJLW4MNq7uv2JwV8w==", "dev": true, "dependencies": { - "tslib": "2.4.0" + "tslib": "2.4.1" }, "funding": { "type": "opencollective", @@ -1873,6 +1873,28 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/@nestjs/websockets": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/websockets/-/websockets-9.2.1.tgz", + "integrity": "sha512-3VYyjLybobsWp6fPtOIGmZL83nV0nzqs+A2KoMf6PxVuFQeTT+BYJqbYE3I1D2wE9d9m81U1efpIeOuL8CXRAQ==", + "dependencies": { + "iterare": "1.2.1", + "object-hash": "3.0.0", + "tslib": "2.4.1" + }, + "peerDependencies": { + "@nestjs/common": "^9.0.0", + "@nestjs/core": "^9.0.0", + "@nestjs/platform-socket.io": "^9.0.0", + "reflect-metadata": "^0.1.12", + "rxjs": "^7.1.0" + }, + "peerDependenciesMeta": { + "@nestjs/platform-socket.io": { + "optional": true + } + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1991,9 +2013,9 @@ } }, "node_modules/@redis/client": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.3.1.tgz", - "integrity": "sha512-FKEHpOu7Q4+cuM6VWjA54988K5jkqOxvhvj2hEGSx086lvKwXyjzO7Lya7hcirZ0/Db8FLBJN7UXsJuyoNWPJg==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.4.2.tgz", + "integrity": "sha512-oUdEjE0I7JS5AyaAjkD3aOXn9NhO7XKyPyXEyrgFDu++VrVBHUPnV6dgEya9TcMuj5nIJRuCzCm8ZP+c9zCHPw==", "dependencies": { "cluster-key-slot": "1.1.1", "generic-pool": "3.9.0", @@ -2028,23 +2050,23 @@ } }, "node_modules/@redis/time-series": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.3.tgz", - "integrity": "sha512-OFp0q4SGrTH0Mruf6oFsHGea58u8vS/iI5+NpYdicaM+7BgqBZH8FFvNZ8rYYLrUO/QRqMq72NpXmxLVNcdmjA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.4.tgz", + "integrity": "sha512-ThUIgo2U/g7cCuZavucQTQzA9g9JbDDY2f64u3AbAoz/8vE2lt2U37LamDUVChhaDA3IRT9R6VvJwqnUfTJzng==", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/@sinclair/typebox": { - "version": "0.24.47", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.47.tgz", - "integrity": "sha512-J4Xw0xYK4h7eC34MNOPQi6IkNxGRck6n4VJpWDzXIFVTW8I/D43Gf+NfWz/v/7NHlzWOPd3+T4PJ4OqklQ2u7A==", + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", "dev": true }, "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", "dev": true, "dependencies": { "type-detect": "4.0.8" @@ -2059,6 +2081,11 @@ "@sinonjs/commons": "^1.7.0" } }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + }, "node_modules/@sqltools/formatter": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz", @@ -2089,9 +2116,9 @@ "devOptional": true }, "node_modules/@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "version": "7.1.20", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", + "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -2121,9 +2148,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", - "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", "dev": true, "dependencies": { "@babel/types": "^7.3.0" @@ -2146,16 +2173,29 @@ "@types/node": "*" } }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + }, "node_modules/@types/cookiejar": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz", "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", "dev": true }, + "node_modules/@types/cors": { + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/eslint": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.7.tgz", - "integrity": "sha512-ehM7cCt2RSFs42mb+lcmhFT9ouIlV92PuaeRGn8N8c98oMjG4Z5pJHA9b1QiCcuqnbPSHcyfiD3mlhqMaHsQIw==", + "version": "8.4.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz", + "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==", "dev": true, "dependencies": { "@types/estree": "*", @@ -2179,12 +2219,12 @@ "dev": true }, "node_modules/@types/express": { - "version": "4.17.14", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", - "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.15.tgz", + "integrity": "sha512-Yv0k4bXGOH+8a+7bELd2PqHQsuiANB+A8a4gnQrkRWzrkKlb6KHaVvyXhqs04sVW/OWlbPyYxRgYlIXLfrufMQ==", "dependencies": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", + "@types/express-serve-static-core": "^4.17.31", "@types/qs": "*", "@types/serve-static": "*" } @@ -2256,15 +2296,6 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, - "node_modules/@types/jsonwebtoken": { - "version": "8.5.9", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz", - "integrity": "sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/mime": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", @@ -2280,9 +2311,9 @@ } }, "node_modules/@types/node": { - "version": "16.11.68", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.68.tgz", - "integrity": "sha512-JkRpuVz3xCNCWaeQ5EHLR/6woMbHZz/jZ7Kmc63AkU+1HxnoUugzSWMck7dsR4DvNYX8jp9wTi9K7WvnxOIQZQ==" + "version": "16.18.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.11.tgz", + "integrity": "sha512-3oJbGBUWuS6ahSnEq1eN2XrCyf4YsWI8OyCvo7c64zQJNplk3mO84t53o8lfTk+2ji59g5ycfc6qQ3fdHliHuA==" }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -2299,17 +2330,6 @@ "@types/express": "*" } }, - "node_modules/@types/passport-jwt": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/passport-jwt/-/passport-jwt-3.0.7.tgz", - "integrity": "sha512-qRQ4qlww1Yhs3IaioDKrsDNmKy6gLDLgFsGwpCnc2YqWovO2Oxu9yCQdWHMJafQ7UIuOba4C4/TNXcGkQfEjlQ==", - "dev": true, - "dependencies": { - "@types/express": "*", - "@types/jsonwebtoken": "*", - "@types/passport-strategy": "*" - } - }, "node_modules/@types/passport-local": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/@types/passport-local/-/passport-local-1.0.34.tgz", @@ -2347,19 +2367,10 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, - "node_modules/@types/redis": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/@types/redis/-/redis-4.0.11.tgz", - "integrity": "sha512-bI+gth8La8Wg/QCR1+V1fhrL9+LZUSWfcqpOj2Kc80ZQ4ffbdL173vQd5wovmoV9i071FU9oP2g6etLuEwb6Rg==", - "deprecated": "This is a stub types definition. redis provides its own type definitions, so you do not need this installed.", - "dependencies": { - "redis": "*" - } - }, "node_modules/@types/semver": { - "version": "7.3.12", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.12.tgz", - "integrity": "sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==", + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, "node_modules/@types/serve-static": { @@ -2378,9 +2389,9 @@ "dev": true }, "node_modules/@types/superagent": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.15.tgz", - "integrity": "sha512-mu/N4uvfDN2zVQQ5AYJI/g4qxn2bHB6521t1UuH09ShNWjebTqN0ZFuYK9uYjcgmI0dTQEs+Owi1EO6U0OkOZQ==", + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.16.tgz", + "integrity": "sha512-tLfnlJf6A5mB6ddqF159GqcDizfzbMUB1/DeT59/wBNqzRTNNKsaw79A/1TZ84X+f/EwWH8FeuSkjlCLyqS/zQ==", "dev": true, "dependencies": { "@types/cookiejar": "*", @@ -2397,14 +2408,14 @@ } }, "node_modules/@types/validator": { - "version": "13.7.9", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.9.tgz", - "integrity": "sha512-y5KJ1PjGXPpU4CZ7lThDu31s+FqvzhqwMOR6Go/x6xaQMFjgzwfzfOvCwABsylr/5n8sB1qFQm1Vi7TaCB8P+A==" + "version": "13.7.10", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.10.tgz", + "integrity": "sha512-t1yxFAR2n0+VO6hd/FJ9F2uezAZVWHLmpmlJzm1eX03+H7+HsuTAp7L8QJs+2pQCfWkP1+EXsGK9Z9v7o/qPVQ==" }, "node_modules/@types/yargs": { - "version": "17.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", - "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", + "version": "17.0.17", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.17.tgz", + "integrity": "sha512-72bWxFKTK6uwWJAVT+3rF6Jo6RTojiJ27FQo8Rf60AL+VZbzoVPnMFhKsUnbjR8A3BTCYQ7Mv3hnl8T0A+CX9g==", "dev": true, "dependencies": { "@types/yargs-parser": "*" @@ -2417,16 +2428,17 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.40.1.tgz", - "integrity": "sha512-FsWboKkWdytGiXT5O1/R9j37YgcjO8MKHSUmWnIEjVaz0krHkplPnYi7mwdb+5+cs0toFNQb0HIrN7zONdIEWg==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.46.1.tgz", + "integrity": "sha512-YpzNv3aayRBwjs4J3oz65eVLXc9xx0PDbIRisHj+dYhvBn02MjYOD96P8YGiWEIFBrojaUjxvkaUpakD82phsA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/type-utils": "5.40.1", - "@typescript-eslint/utils": "5.40.1", + "@typescript-eslint/scope-manager": "5.46.1", + "@typescript-eslint/type-utils": "5.46.1", + "@typescript-eslint/utils": "5.46.1", "debug": "^4.3.4", "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" @@ -2449,14 +2461,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.40.1.tgz", - "integrity": "sha512-IK6x55va5w4YvXd4b3VrXQPldV9vQTxi5ov+g4pMANsXPTXOcfjx08CRR1Dfrcc51syPtXHF5bgLlMHYFrvQtg==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.46.1.tgz", + "integrity": "sha512-RelQ5cGypPh4ySAtfIMBzBGyrNerQcmfA1oJvPj5f+H4jI59rl9xxpn4bonC0tQvUKOEN7eGBFWxFLK3Xepneg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/typescript-estree": "5.40.1", + "@typescript-eslint/scope-manager": "5.46.1", + "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/typescript-estree": "5.46.1", "debug": "^4.3.4" }, "engines": { @@ -2476,13 +2488,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.40.1.tgz", - "integrity": "sha512-jkn4xsJiUQucI16OLCXrLRXDZ3afKhOIqXs4R3O+M00hdQLKR58WuyXPZZjhKLFCEP2g+TXdBRtLQ33UfAdRUg==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.46.1.tgz", + "integrity": "sha512-iOChVivo4jpwUdrJZyXSMrEIM/PvsbbDOX1y3UCKjSgWn+W89skxWaYXACQfxmIGhPVpRWK/VWPYc+bad6smIA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/visitor-keys": "5.40.1" + "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/visitor-keys": "5.46.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2493,13 +2505,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.40.1.tgz", - "integrity": "sha512-DLAs+AHQOe6n5LRraXiv27IYPhleF0ldEmx6yBqBgBLaNRKTkffhV1RPsjoJBhVup2zHxfaRtan8/YRBgYhU9Q==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.46.1.tgz", + "integrity": "sha512-V/zMyfI+jDmL1ADxfDxjZ0EMbtiVqj8LUGPAGyBkXXStWmCUErMpW873zEHsyguWCuq2iN4BrlWUkmuVj84yng==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.40.1", - "@typescript-eslint/utils": "5.40.1", + "@typescript-eslint/typescript-estree": "5.46.1", + "@typescript-eslint/utils": "5.46.1", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -2520,9 +2532,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.40.1.tgz", - "integrity": "sha512-Icg9kiuVJSwdzSQvtdGspOlWNjVDnF3qVIKXdJ103o36yRprdl3Ge5cABQx+csx960nuMF21v8qvO31v9t3OHw==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.46.1.tgz", + "integrity": "sha512-Z5pvlCaZgU+93ryiYUwGwLl9AQVB/PQ1TsJ9NZ/gHzZjN7g9IAn6RSDkpCV8hqTwAiaj6fmCcKSQeBPlIpW28w==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2533,13 +2545,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.40.1.tgz", - "integrity": "sha512-5QTP/nW5+60jBcEPfXy/EZL01qrl9GZtbgDZtDPlfW5zj/zjNrdI2B5zMUHmOsfvOr2cWqwVdWjobCiHcedmQA==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.46.1.tgz", + "integrity": "sha512-j9W4t67QiNp90kh5Nbr1w92wzt+toiIsaVPnEblB2Ih2U9fqBTyqV9T3pYWZBRt6QoMh/zVWP59EpuCjc4VRBg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/visitor-keys": "5.40.1", + "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/visitor-keys": "5.46.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2560,16 +2572,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.40.1.tgz", - "integrity": "sha512-a2TAVScoX9fjryNrW6BZRnreDUszxqm9eQ9Esv8n5nXApMW0zeANUYlwh/DED04SC/ifuBvXgZpIK5xeJHQ3aw==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.46.1.tgz", + "integrity": "sha512-RBdBAGv3oEpFojaCYT4Ghn4775pdjvwfDOfQ2P6qzNVgQOVrnSPe5/Pb88kv7xzYQjoio0eKHKB9GJ16ieSxvA==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/typescript-estree": "5.40.1", + "@typescript-eslint/scope-manager": "5.46.1", + "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/typescript-estree": "5.46.1", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -2586,12 +2598,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.40.1.tgz", - "integrity": "sha512-A2DGmeZ+FMja0geX5rww+DpvILpwo1OsiQs0M+joPWJYsiEFBLsH0y1oFymPNul6Z5okSmHpP4ivkc2N0Cgfkw==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.1.tgz", + "integrity": "sha512-jczZ9noovXwy59KjRTk1OftT78pwygdcmCuBf8yMoWt/8O8l+6x2LSEze0E4TeepXK4MezW3zGSyoDRZK7Y9cg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.40.1", + "@typescript-eslint/types": "5.46.1", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -2773,9 +2785,9 @@ } }, "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "devOptional": true, "bin": { "acorn": "bin/acorn" @@ -2908,9 +2920,9 @@ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" }, "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", @@ -3101,6 +3113,14 @@ } ] }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, "node_modules/base64url": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", @@ -3144,9 +3164,9 @@ } }, "node_modules/body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", @@ -3156,7 +3176,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.10.3", + "qs": "6.11.0", "raw-body": "2.5.1", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -3273,11 +3293,6 @@ "ieee754": "^1.1.13" } }, - "node_modules/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": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -3340,9 +3355,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001422", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001422.tgz", - "integrity": "sha512-hSesn02u1QacQHhaxl/kNMZwqVG35Sz/8DgvmgedxSH8z9UUpcDYSPYgsj3x5dQNRcNp6BwpSfQfVzYUTm+fog==", + "version": "1.0.30001439", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", + "integrity": "sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==", "dev": true, "funding": [ { @@ -3420,10 +3435,13 @@ } }, "node_modules/ci-info": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", - "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==", - "dev": true + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", + "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==", + "dev": true, + "engines": { + "node": ">=8" + } }, "node_modules/cjs-module-lexer": { "version": "1.2.2", @@ -3746,9 +3764,9 @@ } }, "node_modules/cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, "dependencies": { "@types/parse-json": "^4.0.0", @@ -3859,6 +3877,16 @@ "node": ">=0.4.0" } }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -3943,9 +3971,9 @@ } }, "node_modules/dotenv": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", - "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz", + "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==", "engines": { "node": ">=12" } @@ -3958,14 +3986,6 @@ "node": ">=12" } }, - "node_modules/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==", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -4016,10 +4036,46 @@ "once": "^1.4.0" } }, + "node_modules/engine.io": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz", + "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==", + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.3", + "ws": "~8.2.3" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", + "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", + "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -4070,14 +4126,15 @@ } }, "node_modules/eslint": { - "version": "8.25.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.25.0.tgz", - "integrity": "sha512-DVlJOZ4Pn50zcKW5bYH7GQK/9MsoQG2d5eDH0ebEkE8PbgzTTmtt/VTH9GGJ4BfeZCpBLqFfvsjX35UacUL83A==", + "version": "8.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.30.0.tgz", + "integrity": "sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.10.5", + "@eslint/eslintrc": "^1.4.0", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -4093,14 +4150,14 @@ "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", @@ -4279,9 +4336,9 @@ "dev": true }, "node_modules/espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", "dev": true, "dependencies": { "acorn": "^8.8.0", @@ -4513,29 +4570,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -4554,20 +4588,6 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, - "node_modules/express/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", @@ -4628,9 +4648,9 @@ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", + "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -4837,21 +4857,6 @@ "url": "https://ko-fi.com/tunnckoCore/commissions" } }, - "node_modules/formidable/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -5009,9 +5014,9 @@ "dev": true }, "node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -5163,9 +5168,9 @@ ] }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", + "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==", "dev": true, "engines": { "node": ">= 4" @@ -5296,6 +5301,31 @@ "node": ">= 0.10" } }, + "node_modules/ioredis": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.2.4.tgz", + "integrity": "sha512-qIpuAEt32lZJQ0XyrloCRdlEdUUNGG9i0UOk6zgzK6igyudNWqEBxfH6OlbnOOoBBvr1WB02mm8fR55CnikRng==", + "optional": true, + "peer": true, + "dependencies": { + "@ioredis/commands": "^1.1.1", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.0.1", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -5390,6 +5420,15 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -5933,9 +5972,9 @@ } }, "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "engines": { "node": ">=6" @@ -6316,10 +6355,14 @@ } }, "node_modules/js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } }, "node_modules/js-tokens": { "version": "4.0.0", @@ -6369,9 +6412,9 @@ "dev": true }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", + "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", "dev": true, "bin": { "json5": "lib/cli.js" @@ -6398,54 +6441,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", - "dependencies": { - "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" - }, - "engines": { - "node": ">=4", - "npm": ">=1.4.28" - } - }, - "node_modules/jsonwebtoken/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -6478,9 +6473,9 @@ } }, "node_modules/libphonenumber-js": { - "version": "1.10.14", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.14.tgz", - "integrity": "sha512-McGS7GV/WjJ2KjfOGhJU1oJn29RYeo7Q+RpANRbUNMQ9gj5XArpbjurSuyYPTejFwbaUojstQ4XyWCrAzGOUXw==" + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.15.tgz", + "integrity": "sha512-sLeVLmWX17VCKKulc+aDIRHS95TxoTsKMRJi5s5gJdwlqNzMWcBCtSHHruVyXjqfi67daXM2SnLf2juSrdx5Sg==" }, "node_modules/lines-and-columns": { "version": "1.2.4", @@ -6517,35 +6512,19 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "node_modules/lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "optional": true, + "peer": true }, - "node_modules/lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" - }, - "node_modules/lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" - }, - "node_modules/lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", + "optional": true, + "peer": true }, "node_modules/lodash.memoize": { "version": "4.1.2", @@ -6559,11 +6538,6 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" - }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -6680,9 +6654,9 @@ } }, "node_modules/memfs": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.7.tgz", - "integrity": "sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw==", + "version": "3.4.12", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.12.tgz", + "integrity": "sha512-BcjuQn6vfqP+k100e0E9m61Hyqa//Brp+I3f0OBmN0ATHlFA8vx3Lt8z57R3u2bPqe3WGDBC+nF72fTH7isyEw==", "dev": true, "dependencies": { "fs-monkey": "^1.0.3" @@ -6845,6 +6819,12 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -6905,9 +6885,9 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", "dev": true }, "node_modules/normalize-path": { @@ -7220,15 +7200,6 @@ "node": ">= 6.0.0" } }, - "node_modules/passport-jwt": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.0.tgz", - "integrity": "sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg==", - "dependencies": { - "jsonwebtoken": "^8.2.0", - "passport-strategy": "^1.0.0" - } - }, "node_modules/passport-local": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", @@ -7544,9 +7515,9 @@ } }, "node_modules/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz", + "integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -7773,9 +7744,9 @@ } }, "node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dependencies": { "side-channel": "^1.0.4" }, @@ -7895,16 +7866,39 @@ } }, "node_modules/redis": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.4.0.tgz", - "integrity": "sha512-tQyFG6O9iewLxxHYRyirJNklhe2QI7M/0o8q0jk7D9Z/Cxh/7oZrQyHKyjWz0TkkCls8ool/xvhL9K8zRnkaYQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.5.1.tgz", + "integrity": "sha512-oxXSoIqMJCQVBTfxP6BNTCtDMyh9G6Vi5wjdPdV/sRKkufyZslDqCScSGcOr6XGR/reAWZefz7E4leM31RgdBA==", "dependencies": { "@redis/bloom": "1.1.0", - "@redis/client": "1.3.1", + "@redis/client": "1.4.2", "@redis/graph": "1.1.0", "@redis/json": "1.0.4", "@redis/search": "1.1.0", - "@redis/time-series": "1.0.3" + "@redis/time-series": "1.0.4" + } + }, + "node_modules/redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", + "optional": true, + "peer": true, + "dependencies": { + "redis-errors": "^1.0.0" + }, + "engines": { + "node": ">=4" } }, "node_modules/reflect-metadata": { @@ -8072,9 +8066,9 @@ } }, "node_modules/rxjs": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", - "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", + "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", "dependencies": { "tslib": "^2.1.0" } @@ -8330,6 +8324,39 @@ "node": ">=8" } }, + "node_modules/socket.io": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.4.tgz", + "integrity": "sha512-m3GC94iK9MfIEeIBfbhJs5BqFibMtkRk8ZpKwG2QwxV0m/eEhPIV4ara6XCF1LWNAus7z58RodiZlAH71U3EhQ==", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.2.1", + "socket.io-adapter": "~2.4.0", + "socket.io-parser": "~4.2.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", + "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==" + }, + "node_modules/socket.io-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", + "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -8362,6 +8389,7 @@ "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", "dev": true }, "node_modules/split2": { @@ -8379,9 +8407,9 @@ "dev": true }, "node_modules/stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -8399,6 +8427,13 @@ "node": ">=8" } }, + "node_modules/standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", + "optional": true, + "peer": true + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -8496,10 +8531,9 @@ } }, "node_modules/superagent": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.2.tgz", - "integrity": "sha512-QtYZ9uaNAMexI7XWl2vAXAh0j4q9H7T0WVEI/y5qaUB3QLwxo+voUgCQ217AokJzUTIVOp0RTo7fhZrwhD7A2Q==", - "deprecated": "Please use v8.0.0 until https://github.com/visionmedia/superagent/issues/1743 is resolved", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.6.tgz", + "integrity": "sha512-HqSe6DSIh3hEn6cJvCkaM1BLi466f1LHi4yubR0tpewlMpk4RUFFy35bKz8SsPBwYfIIJy5eclp+3tCYAuX0bw==", "dev": true, "dependencies": { "component-emitter": "^1.3.0", @@ -8507,11 +8541,11 @@ "debug": "^4.3.4", "fast-safe-stringify": "^2.1.1", "form-data": "^4.0.0", - "formidable": "^2.0.1", + "formidable": "^2.1.1", "methods": "^1.1.2", "mime": "2.6.0", "qs": "^6.11.0", - "semver": "^7.3.7" + "semver": "^7.3.8" }, "engines": { "node": ">=6.4.0 <13 || >=14" @@ -8529,29 +8563,14 @@ "node": ">=4.0.0" } }, - "node_modules/superagent/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/supertest": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.0.tgz", - "integrity": "sha512-QgWju1cNoacP81Rv88NKkQ4oXTzGg0eNZtOoxp1ROpbS4OHY/eK5b8meShuFtdni161o5X0VQvgo7ErVyKK+Ow==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.3.tgz", + "integrity": "sha512-EMCG6G8gDu5qEqRQ3JjjPs6+FYT1a7Hv5ApHvtSghmOFJYtsU5S+pSb6Y2EUeCEY3CmEL3mmQ8YWlPOzQomabA==", "dev": true, "dependencies": { "methods": "^1.1.2", - "superagent": "^8.0.0" + "superagent": "^8.0.5" }, "engines": { "node": ">=6.4.0" @@ -8628,9 +8647,9 @@ } }, "node_modules/terser": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", - "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.1.tgz", + "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.2", @@ -8872,9 +8891,9 @@ } }, "node_modules/ts-loader": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.1.tgz", - "integrity": "sha512-384TYAqGs70rn9F0VBnh6BPTfhga7yFNdC5gXbQpDrBj9/KsT4iRkGqKXhziofHOlE2j6YEaiTYVGKKvPhGWvw==", + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz", + "integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==", "dev": true, "dependencies": { "chalk": "^4.1.0", @@ -9003,9 +9022,9 @@ } }, "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "node_modules/tsutils": { "version": "3.21.0", @@ -9079,9 +9098,9 @@ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "node_modules/typeorm": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.10.tgz", - "integrity": "sha512-VMKiM84EpJQ+Mz9xDIPqnfplWhyUy1d8ccaKdMY9obifxJOTFnv8GYVyPsGwG8Lk7Nb8MlttHyHWENGAhBA3WA==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.11.tgz", + "integrity": "sha512-pzdOyWbVuz/z8Ww6gqvBW4nylsM0KLdUCDExr2gR20/x1khGSVxQkjNV/3YqliG90jrWzrknYbYscpk8yxFJVg==", "dependencies": { "@sqltools/formatter": "^1.2.2", "app-root-path": "^3.0.0", @@ -9115,7 +9134,7 @@ "peerDependencies": { "@google-cloud/spanner": "^5.18.0", "@sap/hana-client": "^2.12.25", - "better-sqlite3": "^7.1.2", + "better-sqlite3": "^7.1.2 || ^8.0.0", "hdb-pool": "^0.1.6", "ioredis": "^5.0.4", "mongodb": "^3.6.0", @@ -9243,9 +9262,9 @@ } }, "node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "devOptional": true, "bin": { "tsc": "bin/tsc", @@ -9417,10 +9436,11 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/webpack": { - "version": "5.74.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", - "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", + "version": "5.75.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", + "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", "dev": true, + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", @@ -9615,6 +9635,26 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xml2js": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", @@ -9666,9 +9706,9 @@ } }, "node_modules/yargs": { - "version": "17.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz", - "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==", + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -9676,7 +9716,7 @@ "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" }, "engines": { "node": ">=12" @@ -9842,27 +9882,27 @@ } }, "@babel/compat-data": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.4.tgz", - "integrity": "sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", "dev": true }, "@babel/core": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.6.tgz", - "integrity": "sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", + "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", "dev": true, "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.6", - "@babel/helper-compilation-targets": "^7.19.3", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helpers": "^7.19.4", - "@babel/parser": "^7.19.6", + "@babel/generator": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-module-transforms": "^7.20.2", + "@babel/helpers": "^7.20.5", + "@babel/parser": "^7.20.5", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.6", - "@babel/types": "^7.19.4", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -9879,12 +9919,12 @@ } }, "@babel/generator": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.6.tgz", - "integrity": "sha512-oHGRUQeoX1QrKeJIKVe0hwjGqNnVYsM5Nep5zo0uE0m42sLH+Fsd2pStJ5sRM1bNyTUUoz0pe2lTeMJrb/taTA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", "dev": true, "requires": { - "@babel/types": "^7.19.4", + "@babel/types": "^7.20.5", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -9903,12 +9943,12 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", - "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.19.3", + "@babel/compat-data": "^7.20.0", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", "semver": "^6.3.0" @@ -9957,34 +9997,34 @@ } }, "@babel/helper-module-transforms": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.6.tgz", - "integrity": "sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", + "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", "dev": true, "requires": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.19.4", + "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.6", - "@babel/types": "^7.19.4" + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.2" } }, "@babel/helper-plugin-utils": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", - "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", "dev": true }, "@babel/helper-simple-access": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", - "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "dev": true, "requires": { - "@babel/types": "^7.19.4" + "@babel/types": "^7.20.2" } }, "@babel/helper-split-export-declaration": { @@ -10015,14 +10055,14 @@ "dev": true }, "@babel/helpers": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.4.tgz", - "integrity": "sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", "dev": true, "requires": { "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.4", - "@babel/types": "^7.19.4" + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" } }, "@babel/highlight": { @@ -10095,9 +10135,9 @@ } }, "@babel/parser": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.6.tgz", - "integrity": "sha512-h1IUp81s2JYJ3mRkdxJgs4UvmSsRvDrx5ICSJbPvtWYv5i1nTBGcBpnog+89rAFMwvvru6E5NUHdBe01UeSzYA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -10209,12 +10249,12 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", - "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" } }, "@babel/template": { @@ -10229,19 +10269,19 @@ } }, "@babel/traverse": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.6.tgz", - "integrity": "sha512-6l5HrUCzFM04mfbG09AagtYyR2P0B71B1wN7PfSPiksDPz2k5H9CBC1tcZpz2M8OxbKTPccByoOJ22rUKbpmQQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.6", + "@babel/generator": "^7.20.5", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.6", - "@babel/types": "^7.19.4", + "@babel/parser": "^7.20.5", + "@babel/types": "^7.20.5", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -10255,9 +10295,9 @@ } }, "@babel/types": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", - "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", "dev": true, "requires": { "@babel/helper-string-parser": "^7.19.4", @@ -10300,15 +10340,15 @@ } }, "@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", + "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -10337,14 +10377,14 @@ } }, "@humanwhocodes/config-array": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", - "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" } }, "@humanwhocodes/module-importer": { @@ -10359,6 +10399,13 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", + "optional": true, + "peer": true + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -10785,9 +10832,9 @@ } }, "@nestjs/cli": { - "version": "9.1.4", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-9.1.4.tgz", - "integrity": "sha512-cvN4DcLzaqFzKRmpU3tOeLmw7+1p4XXsFLyWgteId0Szf6cAk5KJpD5jl2Kw7f39vNw9Pss8yiJ1q1CD/fcbwQ==", + "version": "9.1.5", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-9.1.5.tgz", + "integrity": "sha512-rSp26+Nv7PFtYrRSP18Gv5ZK8rRSc2SCCF5wh4SdZaVGgkxShpNq9YEfI+ik/uziN3KC5o74ppYRXGj+aHGVsA==", "dev": true, "requires": { "@angular-devkit/core": "14.2.2", @@ -10809,26 +10856,58 @@ "tree-kill": "1.2.2", "tsconfig-paths": "4.1.0", "tsconfig-paths-webpack-plugin": "4.0.0", - "typescript": "4.8.3", + "typescript": "4.8.4", "webpack": "5.74.0", "webpack-node-externals": "3.0.0" }, "dependencies": { "typescript": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz", - "integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "dev": true + }, + "webpack": { + "version": "5.74.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", + "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.10.0", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + } } } }, "@nestjs/common": { - "version": "9.1.4", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-9.1.4.tgz", - "integrity": "sha512-hmGTZ8ShKFDqqlU02uU8e/8PNE4bnES4pcFa6s/T1pLDYWjyf/75Klunro1W4aQPHcxnnohBmB27WxMqFTPEfw==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-9.2.1.tgz", + "integrity": "sha512-nZuo3oDsSSlC5mti/M2aCWTEIfHPGDXmBwWgPeCpRbrNz3IWd109rkajll+yxgidVjznAdBS9y00JkAVJblNYw==", "requires": { "iterare": "1.2.1", - "tslib": "2.4.0", + "tslib": "2.4.1", "uuid": "9.0.0" } }, @@ -10843,11 +10922,6 @@ "uuid": "8.3.2" }, "dependencies": { - "dotenv": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz", - "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==" - }, "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -10856,38 +10930,19 @@ } }, "@nestjs/core": { - "version": "9.1.4", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-9.1.4.tgz", - "integrity": "sha512-S6KpGeKotPYh126hhRqYLhvg9lxSbAmGfEbK8m09crIK7CYP05t32KtT6n12xl5/iva1G4Ch87Z/3rYP76etUg==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-9.2.1.tgz", + "integrity": "sha512-a9GkXuu8uXgNgCVW+17iI8kLCltO+HwHpU2IhR+32JKnN2WEQ1YEWU4t3GJ2MNq44YkjIw9zrKvFkjJBlYrNbQ==", "requires": { "@nuxtjs/opencollective": "0.3.2", "fast-safe-stringify": "2.1.1", "iterare": "1.2.1", "object-hash": "3.0.0", "path-to-regexp": "3.2.0", - "tslib": "2.4.0", + "tslib": "2.4.1", "uuid": "9.0.0" } }, - "@nestjs/jwt": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-9.0.0.tgz", - "integrity": "sha512-ZsXGY/wMYKzEhymw2+dxiwrHTRKIKrGszx6r2EjQqNLypdXMQu0QrujwZJ8k3+XQV4snmuJwwNakQoA2ILfq8w==", - "requires": { - "@types/jsonwebtoken": "8.5.8", - "jsonwebtoken": "8.5.1" - }, - "dependencies": { - "@types/jsonwebtoken": { - "version": "8.5.8", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.8.tgz", - "integrity": "sha512-zm6xBQpFDIDM6o9r6HSgDeIcLy82TKWctCXEPbJJcXb5AKmi5BNNdLXneixK4lplX3PqIVcwLBCGE/kAGnlD4A==", - "requires": { - "@types/node": "*" - } - } - } - }, "@nestjs/mapped-types": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-1.2.0.tgz", @@ -10901,72 +10956,38 @@ "requires": {} }, "@nestjs/platform-express": { - "version": "9.1.4", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-9.1.4.tgz", - "integrity": "sha512-SLJWDa6V54QrUvzKI4Eyt7gyrjV7F9FY1uHFihshjmQfpf0ebCGacR9jzNwf01aHl0BJX3DUn/KYteBjz6DJXw==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-9.2.1.tgz", + "integrity": "sha512-7PecaXt8lrdS1p6Vb1X/am3GGv+EO1VahyDzaEGOK6C0zwhc0VPfLtwihkjjfhS6BjpRIXXgviwEjONUvxVZnA==", "requires": { - "body-parser": "1.20.0", + "body-parser": "1.20.1", "cors": "2.8.5", - "express": "4.18.1", + "express": "4.18.2", "multer": "1.4.4-lts.1", - "tslib": "2.4.0" + "tslib": "2.4.1" + } + }, + "@nestjs/platform-socket.io": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/platform-socket.io/-/platform-socket.io-9.2.1.tgz", + "integrity": "sha512-McLXgmkNDvYhX4RcudpLa/RNvy7NA4vb+7gJxJ12yp189Ijcaoktrex1a4F7PPQ5iKACiI/D0rfvQAe9P1ez+g==", + "requires": { + "socket.io": "4.5.3", + "tslib": "2.4.1" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "socket.io": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.3.tgz", + "integrity": "sha512-zdpnnKU+H6mOp7nYRXH4GNv1ux6HL6+lHL8g7Ds7Lj8CkdK1jJK/dlwsKDculbyOHifcJ0Pr/yeXnZQ5GeFrcg==", "requires": { - "ms": "2.0.0" + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.2.0", + "socket.io-adapter": "~2.4.0", + "socket.io-parser": "~4.2.0" } - }, - "express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.0", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.10.3", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" } } }, @@ -11049,12 +11070,12 @@ } }, "@nestjs/testing": { - "version": "9.1.4", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-9.1.4.tgz", - "integrity": "sha512-gO6b9QJyUajh38DNdss9gSE0UO7x60Jh10W4SwHEjQT1W+yxaEWr3aLyuQItTvUVY6C28XKFLTykMpr8GO28Ug==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-9.2.1.tgz", + "integrity": "sha512-lemXZdRSuqoZ87l0orCrS/c7gqwxeduIFOd21g9g2RUeQ4qlWPegbQDKASzbfC28klPyrgJLW4MNq7uv2JwV8w==", "dev": true, "requires": { - "tslib": "2.4.0" + "tslib": "2.4.1" } }, "@nestjs/typeorm": { @@ -11072,6 +11093,16 @@ } } }, + "@nestjs/websockets": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/websockets/-/websockets-9.2.1.tgz", + "integrity": "sha512-3VYyjLybobsWp6fPtOIGmZL83nV0nzqs+A2KoMf6PxVuFQeTT+BYJqbYE3I1D2wE9d9m81U1efpIeOuL8CXRAQ==", + "requires": { + "iterare": "1.2.1", + "object-hash": "3.0.0", + "tslib": "2.4.1" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -11168,9 +11199,9 @@ "requires": {} }, "@redis/client": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.3.1.tgz", - "integrity": "sha512-FKEHpOu7Q4+cuM6VWjA54988K5jkqOxvhvj2hEGSx086lvKwXyjzO7Lya7hcirZ0/Db8FLBJN7UXsJuyoNWPJg==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.4.2.tgz", + "integrity": "sha512-oUdEjE0I7JS5AyaAjkD3aOXn9NhO7XKyPyXEyrgFDu++VrVBHUPnV6dgEya9TcMuj5nIJRuCzCm8ZP+c9zCHPw==", "requires": { "cluster-key-slot": "1.1.1", "generic-pool": "3.9.0", @@ -11196,21 +11227,21 @@ "requires": {} }, "@redis/time-series": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.3.tgz", - "integrity": "sha512-OFp0q4SGrTH0Mruf6oFsHGea58u8vS/iI5+NpYdicaM+7BgqBZH8FFvNZ8rYYLrUO/QRqMq72NpXmxLVNcdmjA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.4.tgz", + "integrity": "sha512-ThUIgo2U/g7cCuZavucQTQzA9g9JbDDY2f64u3AbAoz/8vE2lt2U37LamDUVChhaDA3IRT9R6VvJwqnUfTJzng==", "requires": {} }, "@sinclair/typebox": { - "version": "0.24.47", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.47.tgz", - "integrity": "sha512-J4Xw0xYK4h7eC34MNOPQi6IkNxGRck6n4VJpWDzXIFVTW8I/D43Gf+NfWz/v/7NHlzWOPd3+T4PJ4OqklQ2u7A==", + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", "dev": true }, "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -11225,6 +11256,11 @@ "@sinonjs/commons": "^1.7.0" } }, + "@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + }, "@sqltools/formatter": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz", @@ -11255,9 +11291,9 @@ "devOptional": true }, "@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "version": "7.1.20", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", + "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -11287,9 +11323,9 @@ } }, "@types/babel__traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", - "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -11312,16 +11348,29 @@ "@types/node": "*" } }, + "@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + }, "@types/cookiejar": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz", "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", "dev": true }, + "@types/cors": { + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "requires": { + "@types/node": "*" + } + }, "@types/eslint": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.7.tgz", - "integrity": "sha512-ehM7cCt2RSFs42mb+lcmhFT9ouIlV92PuaeRGn8N8c98oMjG4Z5pJHA9b1QiCcuqnbPSHcyfiD3mlhqMaHsQIw==", + "version": "8.4.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz", + "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==", "dev": true, "requires": { "@types/estree": "*", @@ -11345,12 +11394,12 @@ "dev": true }, "@types/express": { - "version": "4.17.14", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", - "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.15.tgz", + "integrity": "sha512-Yv0k4bXGOH+8a+7bELd2PqHQsuiANB+A8a4gnQrkRWzrkKlb6KHaVvyXhqs04sVW/OWlbPyYxRgYlIXLfrufMQ==", "requires": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", + "@types/express-serve-static-core": "^4.17.31", "@types/qs": "*", "@types/serve-static": "*" } @@ -11422,15 +11471,6 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, - "@types/jsonwebtoken": { - "version": "8.5.9", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz", - "integrity": "sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/mime": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", @@ -11446,9 +11486,9 @@ } }, "@types/node": { - "version": "16.11.68", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.68.tgz", - "integrity": "sha512-JkRpuVz3xCNCWaeQ5EHLR/6woMbHZz/jZ7Kmc63AkU+1HxnoUugzSWMck7dsR4DvNYX8jp9wTi9K7WvnxOIQZQ==" + "version": "16.18.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.11.tgz", + "integrity": "sha512-3oJbGBUWuS6ahSnEq1eN2XrCyf4YsWI8OyCvo7c64zQJNplk3mO84t53o8lfTk+2ji59g5ycfc6qQ3fdHliHuA==" }, "@types/parse-json": { "version": "4.0.0", @@ -11465,17 +11505,6 @@ "@types/express": "*" } }, - "@types/passport-jwt": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/passport-jwt/-/passport-jwt-3.0.7.tgz", - "integrity": "sha512-qRQ4qlww1Yhs3IaioDKrsDNmKy6gLDLgFsGwpCnc2YqWovO2Oxu9yCQdWHMJafQ7UIuOba4C4/TNXcGkQfEjlQ==", - "dev": true, - "requires": { - "@types/express": "*", - "@types/jsonwebtoken": "*", - "@types/passport-strategy": "*" - } - }, "@types/passport-local": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/@types/passport-local/-/passport-local-1.0.34.tgz", @@ -11513,18 +11542,10 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, - "@types/redis": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/@types/redis/-/redis-4.0.11.tgz", - "integrity": "sha512-bI+gth8La8Wg/QCR1+V1fhrL9+LZUSWfcqpOj2Kc80ZQ4ffbdL173vQd5wovmoV9i071FU9oP2g6etLuEwb6Rg==", - "requires": { - "redis": "*" - } - }, "@types/semver": { - "version": "7.3.12", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.12.tgz", - "integrity": "sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==", + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, "@types/serve-static": { @@ -11543,9 +11564,9 @@ "dev": true }, "@types/superagent": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.15.tgz", - "integrity": "sha512-mu/N4uvfDN2zVQQ5AYJI/g4qxn2bHB6521t1UuH09ShNWjebTqN0ZFuYK9uYjcgmI0dTQEs+Owi1EO6U0OkOZQ==", + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.16.tgz", + "integrity": "sha512-tLfnlJf6A5mB6ddqF159GqcDizfzbMUB1/DeT59/wBNqzRTNNKsaw79A/1TZ84X+f/EwWH8FeuSkjlCLyqS/zQ==", "dev": true, "requires": { "@types/cookiejar": "*", @@ -11562,14 +11583,14 @@ } }, "@types/validator": { - "version": "13.7.9", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.9.tgz", - "integrity": "sha512-y5KJ1PjGXPpU4CZ7lThDu31s+FqvzhqwMOR6Go/x6xaQMFjgzwfzfOvCwABsylr/5n8sB1qFQm1Vi7TaCB8P+A==" + "version": "13.7.10", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.10.tgz", + "integrity": "sha512-t1yxFAR2n0+VO6hd/FJ9F2uezAZVWHLmpmlJzm1eX03+H7+HsuTAp7L8QJs+2pQCfWkP1+EXsGK9Z9v7o/qPVQ==" }, "@types/yargs": { - "version": "17.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", - "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", + "version": "17.0.17", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.17.tgz", + "integrity": "sha512-72bWxFKTK6uwWJAVT+3rF6Jo6RTojiJ27FQo8Rf60AL+VZbzoVPnMFhKsUnbjR8A3BTCYQ7Mv3hnl8T0A+CX9g==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -11582,69 +11603,70 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.40.1.tgz", - "integrity": "sha512-FsWboKkWdytGiXT5O1/R9j37YgcjO8MKHSUmWnIEjVaz0krHkplPnYi7mwdb+5+cs0toFNQb0HIrN7zONdIEWg==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.46.1.tgz", + "integrity": "sha512-YpzNv3aayRBwjs4J3oz65eVLXc9xx0PDbIRisHj+dYhvBn02MjYOD96P8YGiWEIFBrojaUjxvkaUpakD82phsA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/type-utils": "5.40.1", - "@typescript-eslint/utils": "5.40.1", + "@typescript-eslint/scope-manager": "5.46.1", + "@typescript-eslint/type-utils": "5.46.1", + "@typescript-eslint/utils": "5.46.1", "debug": "^4.3.4", "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" } }, "@typescript-eslint/parser": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.40.1.tgz", - "integrity": "sha512-IK6x55va5w4YvXd4b3VrXQPldV9vQTxi5ov+g4pMANsXPTXOcfjx08CRR1Dfrcc51syPtXHF5bgLlMHYFrvQtg==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.46.1.tgz", + "integrity": "sha512-RelQ5cGypPh4ySAtfIMBzBGyrNerQcmfA1oJvPj5f+H4jI59rl9xxpn4bonC0tQvUKOEN7eGBFWxFLK3Xepneg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/typescript-estree": "5.40.1", + "@typescript-eslint/scope-manager": "5.46.1", + "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/typescript-estree": "5.46.1", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.40.1.tgz", - "integrity": "sha512-jkn4xsJiUQucI16OLCXrLRXDZ3afKhOIqXs4R3O+M00hdQLKR58WuyXPZZjhKLFCEP2g+TXdBRtLQ33UfAdRUg==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.46.1.tgz", + "integrity": "sha512-iOChVivo4jpwUdrJZyXSMrEIM/PvsbbDOX1y3UCKjSgWn+W89skxWaYXACQfxmIGhPVpRWK/VWPYc+bad6smIA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/visitor-keys": "5.40.1" + "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/visitor-keys": "5.46.1" } }, "@typescript-eslint/type-utils": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.40.1.tgz", - "integrity": "sha512-DLAs+AHQOe6n5LRraXiv27IYPhleF0ldEmx6yBqBgBLaNRKTkffhV1RPsjoJBhVup2zHxfaRtan8/YRBgYhU9Q==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.46.1.tgz", + "integrity": "sha512-V/zMyfI+jDmL1ADxfDxjZ0EMbtiVqj8LUGPAGyBkXXStWmCUErMpW873zEHsyguWCuq2iN4BrlWUkmuVj84yng==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.40.1", - "@typescript-eslint/utils": "5.40.1", + "@typescript-eslint/typescript-estree": "5.46.1", + "@typescript-eslint/utils": "5.46.1", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.40.1.tgz", - "integrity": "sha512-Icg9kiuVJSwdzSQvtdGspOlWNjVDnF3qVIKXdJ103o36yRprdl3Ge5cABQx+csx960nuMF21v8qvO31v9t3OHw==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.46.1.tgz", + "integrity": "sha512-Z5pvlCaZgU+93ryiYUwGwLl9AQVB/PQ1TsJ9NZ/gHzZjN7g9IAn6RSDkpCV8hqTwAiaj6fmCcKSQeBPlIpW28w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.40.1.tgz", - "integrity": "sha512-5QTP/nW5+60jBcEPfXy/EZL01qrl9GZtbgDZtDPlfW5zj/zjNrdI2B5zMUHmOsfvOr2cWqwVdWjobCiHcedmQA==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.46.1.tgz", + "integrity": "sha512-j9W4t67QiNp90kh5Nbr1w92wzt+toiIsaVPnEblB2Ih2U9fqBTyqV9T3pYWZBRt6QoMh/zVWP59EpuCjc4VRBg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/visitor-keys": "5.40.1", + "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/visitor-keys": "5.46.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -11653,28 +11675,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.40.1.tgz", - "integrity": "sha512-a2TAVScoX9fjryNrW6BZRnreDUszxqm9eQ9Esv8n5nXApMW0zeANUYlwh/DED04SC/ifuBvXgZpIK5xeJHQ3aw==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.46.1.tgz", + "integrity": "sha512-RBdBAGv3oEpFojaCYT4Ghn4775pdjvwfDOfQ2P6qzNVgQOVrnSPe5/Pb88kv7xzYQjoio0eKHKB9GJ16ieSxvA==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.40.1", - "@typescript-eslint/types": "5.40.1", - "@typescript-eslint/typescript-estree": "5.40.1", + "@typescript-eslint/scope-manager": "5.46.1", + "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/typescript-estree": "5.46.1", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.40.1.tgz", - "integrity": "sha512-A2DGmeZ+FMja0geX5rww+DpvILpwo1OsiQs0M+joPWJYsiEFBLsH0y1oFymPNul6Z5okSmHpP4ivkc2N0Cgfkw==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.1.tgz", + "integrity": "sha512-jczZ9noovXwy59KjRTk1OftT78pwygdcmCuBf8yMoWt/8O8l+6x2LSEze0E4TeepXK4MezW3zGSyoDRZK7Y9cg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.40.1", + "@typescript-eslint/types": "5.46.1", "eslint-visitor-keys": "^3.3.0" } }, @@ -11846,9 +11868,9 @@ } }, "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "devOptional": true }, "acorn-import-assertions": { @@ -11934,9 +11956,9 @@ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" }, "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -12079,6 +12101,11 @@ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" + }, "base64url": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", @@ -12115,9 +12142,9 @@ } }, "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "requires": { "bytes": "3.1.2", "content-type": "~1.0.4", @@ -12127,7 +12154,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.10.3", + "qs": "6.11.0", "raw-body": "2.5.1", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -12206,11 +12233,6 @@ "ieee754": "^1.1.13" } }, - "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": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" - }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -12255,9 +12277,9 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "caniuse-lite": { - "version": "1.0.30001422", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001422.tgz", - "integrity": "sha512-hSesn02u1QacQHhaxl/kNMZwqVG35Sz/8DgvmgedxSH8z9UUpcDYSPYgsj3x5dQNRcNp6BwpSfQfVzYUTm+fog==", + "version": "1.0.30001439", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", + "integrity": "sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==", "dev": true }, "chalk": { @@ -12305,9 +12327,9 @@ "dev": true }, "ci-info": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", - "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", + "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==", "dev": true }, "cjs-module-lexer": { @@ -12557,9 +12579,9 @@ } }, "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, "requires": { "@types/parse-json": "^4.0.0", @@ -12637,6 +12659,13 @@ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true }, + "denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "optional": true, + "peer": true + }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -12699,23 +12728,15 @@ } }, "dotenv": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", - "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz", + "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==" }, "dotenv-expand": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-8.0.3.tgz", "integrity": "sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==" }, - "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", @@ -12757,10 +12778,39 @@ "once": "^1.4.0" } }, + "engine.io": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz", + "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==", + "requires": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.3", + "ws": "~8.2.3" + }, + "dependencies": { + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + } + } + }, + "engine.io-parser": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", + "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==" + }, "enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", + "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -12799,14 +12849,15 @@ "dev": true }, "eslint": { - "version": "8.25.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.25.0.tgz", - "integrity": "sha512-DVlJOZ4Pn50zcKW5bYH7GQK/9MsoQG2d5eDH0ebEkE8PbgzTTmtt/VTH9GGJ4BfeZCpBLqFfvsjX35UacUL83A==", + "version": "8.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.30.0.tgz", + "integrity": "sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.10.5", + "@eslint/eslintrc": "^1.4.0", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -12822,14 +12873,14 @@ "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", @@ -12949,9 +13000,9 @@ "dev": true }, "espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", "dev": true, "requires": { "acorn": "^8.8.0", @@ -13096,25 +13147,6 @@ "vary": "~1.1.2" }, "dependencies": { - "body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - } - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -13132,14 +13164,6 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "requires": { - "side-channel": "^1.0.4" - } } } }, @@ -13232,9 +13256,9 @@ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" }, "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", + "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -13392,17 +13416,6 @@ "hexoid": "^1.0.0", "once": "^1.4.0", "qs": "^6.11.0" - }, - "dependencies": { - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - } } }, "forwarded": { @@ -13516,9 +13529,9 @@ "dev": true }, "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -13617,9 +13630,9 @@ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", + "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==", "dev": true }, "import-fresh": { @@ -13716,6 +13729,24 @@ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, + "ioredis": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.2.4.tgz", + "integrity": "sha512-qIpuAEt32lZJQ0XyrloCRdlEdUUNGG9i0UOk6zgzK6igyudNWqEBxfH6OlbnOOoBBvr1WB02mm8fR55CnikRng==", + "optional": true, + "peer": true, + "requires": { + "@ioredis/commands": "^1.1.1", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.0.1", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + } + }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -13783,6 +13814,12 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -14185,9 +14222,9 @@ } }, "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "requires": {} }, @@ -14487,9 +14524,9 @@ } }, "js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", "dev": true }, "js-tokens": { @@ -14531,9 +14568,9 @@ "dev": true }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", + "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", "dev": true }, "jsonc-parser": { @@ -14552,49 +14589,6 @@ "universalify": "^2.0.0" } }, - "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": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "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" - } - }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -14618,9 +14612,9 @@ } }, "libphonenumber-js": { - "version": "1.10.14", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.14.tgz", - "integrity": "sha512-McGS7GV/WjJ2KjfOGhJU1oJn29RYeo7Q+RpANRbUNMQ9gj5XArpbjurSuyYPTejFwbaUojstQ4XyWCrAzGOUXw==" + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.15.tgz", + "integrity": "sha512-sLeVLmWX17VCKKulc+aDIRHS95TxoTsKMRJi5s5gJdwlqNzMWcBCtSHHruVyXjqfi67daXM2SnLf2juSrdx5Sg==" }, "lines-and-columns": { "version": "1.2.4", @@ -14648,35 +14642,19 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "optional": true, + "peer": true }, - "lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" - }, - "lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" - }, - "lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", + "optional": true, + "peer": true }, "lodash.memoize": { "version": "4.1.2", @@ -14690,11 +14668,6 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" - }, "log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -14779,9 +14752,9 @@ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "memfs": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.7.tgz", - "integrity": "sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw==", + "version": "3.4.12", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.12.tgz", + "integrity": "sha512-BcjuQn6vfqP+k100e0E9m61Hyqa//Brp+I3f0OBmN0ATHlFA8vx3Lt8z57R3u2bPqe3WGDBC+nF72fTH7isyEw==", "dev": true, "requires": { "fs-monkey": "^1.0.3" @@ -14905,6 +14878,12 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -14951,9 +14930,9 @@ "dev": true }, "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", "dev": true }, "normalize-path": { @@ -15182,15 +15161,6 @@ "passport-oauth2": "^1.4.0" } }, - "passport-jwt": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.0.tgz", - "integrity": "sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg==", - "requires": { - "jsonwebtoken": "^8.2.0", - "passport-strategy": "^1.0.0" - } - }, "passport-local": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", @@ -15416,9 +15386,9 @@ "dev": true }, "prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz", + "integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==", "dev": true }, "prettier-linter-helpers": { @@ -15589,9 +15559,9 @@ } }, "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "requires": { "side-channel": "^1.0.4" } @@ -15678,16 +15648,33 @@ } }, "redis": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.4.0.tgz", - "integrity": "sha512-tQyFG6O9iewLxxHYRyirJNklhe2QI7M/0o8q0jk7D9Z/Cxh/7oZrQyHKyjWz0TkkCls8ool/xvhL9K8zRnkaYQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.5.1.tgz", + "integrity": "sha512-oxXSoIqMJCQVBTfxP6BNTCtDMyh9G6Vi5wjdPdV/sRKkufyZslDqCScSGcOr6XGR/reAWZefz7E4leM31RgdBA==", "requires": { "@redis/bloom": "1.1.0", - "@redis/client": "1.3.1", + "@redis/client": "1.4.2", "@redis/graph": "1.1.0", "@redis/json": "1.0.4", "@redis/search": "1.1.0", - "@redis/time-series": "1.0.3" + "@redis/time-series": "1.0.4" + } + }, + "redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", + "optional": true, + "peer": true + }, + "redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", + "optional": true, + "peer": true, + "requires": { + "redis-errors": "^1.0.0" } }, "reflect-metadata": { @@ -15797,9 +15784,9 @@ } }, "rxjs": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", - "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", + "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", "requires": { "tslib": "^2.1.0" } @@ -16001,6 +15988,33 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "socket.io": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.4.tgz", + "integrity": "sha512-m3GC94iK9MfIEeIBfbhJs5BqFibMtkRk8ZpKwG2QwxV0m/eEhPIV4ara6XCF1LWNAus7z58RodiZlAH71U3EhQ==", + "requires": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.2.1", + "socket.io-adapter": "~2.4.0", + "socket.io-parser": "~4.2.1" + } + }, + "socket.io-adapter": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", + "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==" + }, + "socket.io-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", + "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + } + }, "source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -16043,9 +16057,9 @@ "dev": true }, "stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -16059,6 +16073,13 @@ } } }, + "standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", + "optional": true, + "peer": true + }, "statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -16131,9 +16152,9 @@ "dev": true }, "superagent": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.2.tgz", - "integrity": "sha512-QtYZ9uaNAMexI7XWl2vAXAh0j4q9H7T0WVEI/y5qaUB3QLwxo+voUgCQ217AokJzUTIVOp0RTo7fhZrwhD7A2Q==", + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.6.tgz", + "integrity": "sha512-HqSe6DSIh3hEn6cJvCkaM1BLi466f1LHi4yubR0tpewlMpk4RUFFy35bKz8SsPBwYfIIJy5eclp+3tCYAuX0bw==", "dev": true, "requires": { "component-emitter": "^1.3.0", @@ -16141,11 +16162,11 @@ "debug": "^4.3.4", "fast-safe-stringify": "^2.1.1", "form-data": "^4.0.0", - "formidable": "^2.0.1", + "formidable": "^2.1.1", "methods": "^1.1.2", "mime": "2.6.0", "qs": "^6.11.0", - "semver": "^7.3.7" + "semver": "^7.3.8" }, "dependencies": { "mime": { @@ -16153,26 +16174,17 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } } } }, "supertest": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.0.tgz", - "integrity": "sha512-QgWju1cNoacP81Rv88NKkQ4oXTzGg0eNZtOoxp1ROpbS4OHY/eK5b8meShuFtdni161o5X0VQvgo7ErVyKK+Ow==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.3.tgz", + "integrity": "sha512-EMCG6G8gDu5qEqRQ3JjjPs6+FYT1a7Hv5ApHvtSghmOFJYtsU5S+pSb6Y2EUeCEY3CmEL3mmQ8YWlPOzQomabA==", "dev": true, "requires": { "methods": "^1.1.2", - "superagent": "^8.0.0" + "superagent": "^8.0.5" } }, "supports-color": { @@ -16222,9 +16234,9 @@ } }, "terser": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", - "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.1.tgz", + "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==", "dev": true, "requires": { "@jridgewell/source-map": "^0.3.2", @@ -16383,9 +16395,9 @@ } }, "ts-loader": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.1.tgz", - "integrity": "sha512-384TYAqGs70rn9F0VBnh6BPTfhga7yFNdC5gXbQpDrBj9/KsT4iRkGqKXhziofHOlE2j6YEaiTYVGKKvPhGWvw==", + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz", + "integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==", "dev": true, "requires": { "chalk": "^4.1.0", @@ -16470,9 +16482,9 @@ } }, "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "tsutils": { "version": "3.21.0", @@ -16527,9 +16539,9 @@ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "typeorm": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.10.tgz", - "integrity": "sha512-VMKiM84EpJQ+Mz9xDIPqnfplWhyUy1d8ccaKdMY9obifxJOTFnv8GYVyPsGwG8Lk7Nb8MlttHyHWENGAhBA3WA==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.11.tgz", + "integrity": "sha512-pzdOyWbVuz/z8Ww6gqvBW4nylsM0KLdUCDExr2gR20/x1khGSVxQkjNV/3YqliG90jrWzrknYbYscpk8yxFJVg==", "requires": { "@sqltools/formatter": "^1.2.2", "app-root-path": "^3.0.0", @@ -16581,9 +16593,9 @@ } }, "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "devOptional": true }, "uid-safe": { @@ -16705,10 +16717,11 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "webpack": { - "version": "5.74.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", - "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", + "version": "5.75.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", + "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", "dev": true, + "peer": true, "requires": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", @@ -16845,6 +16858,12 @@ "signal-exit": "^3.0.7" } }, + "ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "requires": {} + }, "xml2js": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", @@ -16881,9 +16900,9 @@ "dev": true }, "yargs": { - "version": "17.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz", - "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==", + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", "requires": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -16891,7 +16910,7 @@ "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" } }, "yargs-parser": { diff --git a/srcs/requirements/nestjs/api_back/package.json b/srcs/requirements/nestjs/api_back/package.json index f92f86b3..4e8c4666 100644 --- a/srcs/requirements/nestjs/api_back/package.json +++ b/srcs/requirements/nestjs/api_back/package.json @@ -24,13 +24,13 @@ "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.2.0", "@nestjs/core": "^9.0.0", - "@nestjs/jwt": "^9.0.0", "@nestjs/mapped-types": "^1.2.0", "@nestjs/passport": "^9.0.0", "@nestjs/platform-express": "^9.0.0", + "@nestjs/platform-socket.io": "^9.2.1", "@nestjs/typeorm": "^9.0.1", + "@nestjs/websockets": "^9.2.1", "@types/express-session": "^1.17.5", - "@types/redis": "^4.0.11", "@types/validator": "^13.7.9", "class-transformer": "^0.5.1", "class-validator": "^0.13.2", @@ -41,7 +41,6 @@ "otplib": "^12.0.1", "passport": "^0.6.0", "passport-42": "^1.2.6", - "passport-jwt": "^4.0.0", "passport-local": "^1.0.0", "pg": "^8.8.0", "qrcode": "^1.5.1", @@ -49,6 +48,7 @@ "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.2.0", + "socket.io": "^4.5.4", "typeorm": "^0.3.10", "uuid": "^9.0.0" }, @@ -59,8 +59,7 @@ "@types/express": "^4.17.13", "@types/jest": "28.1.8", "@types/multer": "^1.4.7", - "@types/node": "^16.0.0", - "@types/passport-jwt": "^3.0.7", + "@types/node": "^16.18.11", "@types/passport-local": "^1.0.34", "@types/supertest": "^2.0.11", "@typescript-eslint/eslint-plugin": "^5.0.0", diff --git a/srcs/requirements/nestjs/api_back/src/app.module.ts b/srcs/requirements/nestjs/api_back/src/app.module.ts index 837f8baf..a0e5bc5e 100644 --- a/srcs/requirements/nestjs/api_back/src/app.module.ts +++ b/srcs/requirements/nestjs/api_back/src/app.module.ts @@ -7,29 +7,35 @@ import { ConfigModule } from '@nestjs/config'; import { FriendshipsModule } from './friendship/friendships.module'; import { AuthenticationModule } from './auth/42/authentication.module'; import { PassportModule } from '@nestjs/passport'; -// import { GameModule } from './game/game/game.module'; +import { GameModule } from './game/game.module'; +import { ChatGateway } from './chat/chat.gateway'; @Module({ - imports: [UsersModule, - AuthenticationModule, - PassportModule.register({ session: true }), - FriendshipsModule, - ConfigModule.forRoot(), - TypeOrmModule.forRoot({ - type: 'postgres', - host: process.env.POSTGRES_HOST, - port: parseInt(process.env.POSTGRES_PORT), - username: process.env.POSTGRES_USER, - password: process.env.POSTGRES_PASSWORD, - database: process.env.POSTGRES_DATABASE, - autoLoadEntities: true, - //ne pas synchroniser quand on est en prod. Trouver un moyen de set ça, sûrement - //avec une classe pour le module - synchronize: true, - }), - // GameModule, -], + imports: [ + UsersModule, + AuthenticationModule, + PassportModule.register({ session: true }), + FriendshipsModule, + GameModule, + ConfigModule.forRoot(), + TypeOrmModule.forRoot({ + type: 'postgres', + host: process.env.POSTGRES_HOST, + port: parseInt(process.env.POSTGRES_PORT), + username: process.env.POSTGRES_USER, + password: process.env.POSTGRES_PASSWORD, + database: process.env.POSTGRES_DATABASE, + autoLoadEntities: true, + //ne pas synchroniser quand on est en prod. Trouver un moyen de set ça, sûrement + //avec une classe pour le module + synchronize: true, + }), + // GameModule, + ], controllers: [AppController], - providers: [AppService], + providers: [ + AppService, + ChatGateway, + ], }) export class AppModule {} diff --git a/srcs/requirements/nestjs/api_back/src/auth/42/authentication.controller.ts b/srcs/requirements/nestjs/api_back/src/auth/42/authentication.controller.ts index 6746e911..44de4932 100644 --- a/srcs/requirements/nestjs/api_back/src/auth/42/authentication.controller.ts +++ b/srcs/requirements/nestjs/api_back/src/auth/42/authentication.controller.ts @@ -37,10 +37,10 @@ export class AuthenticationController { const user : User = request.user if (user.isEnabledTwoFactorAuth === false || user.isTwoFactorAuthenticated === true){ console.log('ON VA VERS PROFILE'); - return response.status(200).redirect('http://transcendance:8080/#/profile'); + return response.status(200).redirect('http://' + process.env.WEBSITE_HOST + ':' + process.env.WEBSITE_PORT + '/#/profile'); } console.log('ON VA VERS 2FA') - return response.status(200).redirect('http://transcendance:8080/#/2fa'); + return response.status(200).redirect('http://' + process.env.WEBSITE_HOST + ':' + process.env.WEBSITE_PORT + '/#/2fa'); } /** @@ -83,6 +83,6 @@ export class AuthenticationController { throw new UnauthorizedException('Wrong Code.'); await this.userService.authenticateUserWith2FA(request.user.id); console.log('ON REDIRIGE'); - return response.status(200).redirect('http://transcendance:8080/#/profile'); + return response.status(200).redirect('http://' + process.env.WEBSITE_HOST + ':' + process.env.WEBSITE_PORT + '/#/profile'); } } diff --git a/srcs/requirements/nestjs/api_back/src/auth/42/strategy/42strategy.ts b/srcs/requirements/nestjs/api_back/src/auth/42/strategy/42strategy.ts index 6b43659c..6670477a 100644 --- a/srcs/requirements/nestjs/api_back/src/auth/42/strategy/42strategy.ts +++ b/srcs/requirements/nestjs/api_back/src/auth/42/strategy/42strategy.ts @@ -18,7 +18,7 @@ import { CreateUsersDto } from "src/users/dto/create-users.dto"; async validate(accessToken: string, refreshToken: string, profile: Profile, callbackURL: string) { console.log("Validate inside strategy.ts"); console.log(profile.id, profile.username, profile.phoneNumbers[0].value, profile.emails[0].value, profile.photos[0].value); - const userDTO: CreateUsersDto = { fortyTwoId: profile.id, username: profile.username, email: profile.emails[0].value, image_url: 'default.png', isEnabledTwoFactorAuth: false , status: "connected" }; + const userDTO: CreateUsersDto = { fortyTwoId: profile.id, username: profile.username, email: profile.emails[0].value, image_url: 'default.png', isEnabledTwoFactorAuth: false , status: "Connected" }; const user = await this.authenticationService.validateUser(userDTO); if (!user) throw new UnauthorizedException(); diff --git a/srcs/requirements/nestjs/api_back/src/chat/chat.gateway.ts b/srcs/requirements/nestjs/api_back/src/chat/chat.gateway.ts new file mode 100644 index 00000000..0cf3ba6a --- /dev/null +++ b/srcs/requirements/nestjs/api_back/src/chat/chat.gateway.ts @@ -0,0 +1,44 @@ +import { + WebSocketGateway, + SubscribeMessage, + WebSocketServer, + MessageBody, + OnGatewayConnection, + OnGatewayDisconnect, +} from '@nestjs/websockets'; +import { UsersService } from 'src/users/users.service'; +import { PaginationQueryDto } from 'src/common/dto/pagination-query.dto'; + +@WebSocketGateway(5000, { + path: '/chat', +}) + +export class ChatGateway + implements OnGatewayConnection, OnGatewayDisconnect +{ + constructor + ( + private usersService: UsersService, + ) {} + + @WebSocketServer() + server; + + // how to guard the handleConnection ? + // https://github.com/nestjs/nest/issues/882 + async handleConnection(client) { + // const paginationQuery = new PaginationQueryDto(); + // const users = await this.usersService.findAll(paginationQuery); + + // const users = await this.usersService.findAll(client); + // const users = await this.usersService.findAll(client); + console.log('---- Client connected :', client.id); + // console.log('users :', users); + } + handleDisconnect(client) { + console.log('---- client disconnected :', client.id); + } + /* + */ +} + diff --git a/srcs/requirements/nestjs/api_back/src/common/constants/constants.ts b/srcs/requirements/nestjs/api_back/src/common/constants/constants.ts index b10583b0..350ad38b 100644 --- a/srcs/requirements/nestjs/api_back/src/common/constants/constants.ts +++ b/srcs/requirements/nestjs/api_back/src/common/constants/constants.ts @@ -8,6 +8,12 @@ const MIME_TYPES = { 'image/png': 'png' }; +export enum STATUS { + CONNECTED = 'Connected', + DISCONNECTED = 'Disconnected', + IN_GAME = 'In Game', + IN_POOL = 'In Pool', +} export const storageForAvatar = { storage: diskStorage({ @@ -18,5 +24,13 @@ export const storageForAvatar = { const extension : string = MIME_TYPES[file.mimetype]; cb(null, `${filename}${extension}`); } - }) + }), + fileFilter: (req, file, cb) => { + if (file.mimetype === 'image/png' || file.mimetype === 'image/jpg' || file.mimetype === 'image/jpeg') { + cb(null, true); + } + else { + cb(null, false); + } + } } diff --git a/srcs/requirements/nestjs/api_back/src/game/dto/create-party.dto.ts b/srcs/requirements/nestjs/api_back/src/game/dto/create-party.dto.ts deleted file mode 100644 index 14d2e14c..00000000 --- a/srcs/requirements/nestjs/api_back/src/game/dto/create-party.dto.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { IsBoolean, IsEmail, IsNotEmpty, IsString } from 'class-validator'; - -export class CreateUsersDto { - @IsString() - @IsNotEmpty() - readonly username: string; - readonly fortyTwoId: string; - @IsEmail() - readonly email: string; - @IsString() - readonly image_url: string; - @IsString() - readonly status: string; - @IsBoolean() - readonly isEnabledTwoFactorAuth: boolean; -} diff --git a/srcs/requirements/nestjs/api_back/src/game/dto/createGame.dto.ts b/srcs/requirements/nestjs/api_back/src/game/dto/createGame.dto.ts new file mode 100644 index 00000000..ddce81b3 --- /dev/null +++ b/srcs/requirements/nestjs/api_back/src/game/dto/createGame.dto.ts @@ -0,0 +1,19 @@ +import { IsBoolean, IsNotEmpty, IsNumber, IsString } from "class-validator"; + +export class CreateGameDto { + @IsString() + @IsNotEmpty() + gameServerIdOfTheMatch : string + @IsNumber() + @IsNotEmpty() + gameOptions: number + @IsString() + @IsNotEmpty() + playerOneUsername : string + @IsString() + playerTwoUsername : string + @IsNumber() + playerTwoUsernameResult : number + @IsNumber() + playerOneUsernameResult : number +} diff --git a/srcs/requirements/nestjs/api_back/src/game/dto/grantTicket.dto.ts b/srcs/requirements/nestjs/api_back/src/game/dto/grantTicket.dto.ts new file mode 100644 index 00000000..c010fc11 --- /dev/null +++ b/srcs/requirements/nestjs/api_back/src/game/dto/grantTicket.dto.ts @@ -0,0 +1,14 @@ +import { IsBoolean, IsEmpty, IsInt, IsNotEmpty, IsNumber, IsString } from "class-validator"; +import { IsNull } from "typeorm"; + +export class GrantTicketDto { + @IsString() + @IsNotEmpty() + playerOneUsername : string + @IsString() + playerTwoUsername : string + @IsNumber() + gameOptions : number + @IsBoolean() + isGameIsWithInvitation : boolean +} diff --git a/srcs/requirements/nestjs/api_back/src/game/dto/updateGame.dto.ts b/srcs/requirements/nestjs/api_back/src/game/dto/updateGame.dto.ts new file mode 100644 index 00000000..29f55473 --- /dev/null +++ b/srcs/requirements/nestjs/api_back/src/game/dto/updateGame.dto.ts @@ -0,0 +1,5 @@ +import { OmitType } from "@nestjs/mapped-types"; +import { IsBoolean, IsNotEmpty, IsNumber, IsString } from "class-validator"; +import { CreateGameDto } from "./createGame.dto"; + +export class UpdateGameDto extends OmitType(CreateGameDto, ['playerOneUsername', 'playerTwoUsername', 'gameOptions'] as const){} diff --git a/srcs/requirements/nestjs/api_back/src/game/dto/validateTicket.dto.ts b/srcs/requirements/nestjs/api_back/src/game/dto/validateTicket.dto.ts new file mode 100644 index 00000000..8c594dda --- /dev/null +++ b/srcs/requirements/nestjs/api_back/src/game/dto/validateTicket.dto.ts @@ -0,0 +1,16 @@ +import { IsBase64, IsBoolean, IsEmpty, IsNotEmpty, IsNumber, IsString } from "class-validator"; + +export class ValidateTicketDto { + @IsString() + @IsNotEmpty() + playerOneUsername : string + @IsString() + playerTwoUsername : string + @IsNumber() + gameOptions : number + @IsBoolean() + isGameIsWithInvitation : boolean + @IsBase64() + @IsNotEmpty() + token : string +} diff --git a/srcs/requirements/nestjs/api_back/src/game/entity/game.entity.ts b/srcs/requirements/nestjs/api_back/src/game/entity/game.entity.ts new file mode 100644 index 00000000..11386c4b --- /dev/null +++ b/srcs/requirements/nestjs/api_back/src/game/entity/game.entity.ts @@ -0,0 +1,28 @@ +import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; + +@Entity('game') +export class Game { + @PrimaryGeneratedColumn() + id: number; + + @Column() + playerOneUsername: string + + @Column() + playerTwoUsername: string + + @Column({default : 0, nullable : true}) + playerOneUsernameResult : number + + @Column({default : 0, nullable : true}) + playerTwoUsernameResult : number + + @Column({default : 0}) + gameOptions: number + + @Column({unique : true}) + gameServerIdOfTheMatch: string + + @Column({default: false, nullable : true}) //éric pourra trouver un meilleur mot : ongoing ? + isMatchIsFinished: boolean +} diff --git a/srcs/requirements/nestjs/api_back/src/game/entity/tokenGame.entity.ts b/srcs/requirements/nestjs/api_back/src/game/entity/tokenGame.entity.ts new file mode 100644 index 00000000..9481b32e --- /dev/null +++ b/srcs/requirements/nestjs/api_back/src/game/entity/tokenGame.entity.ts @@ -0,0 +1,22 @@ +import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; + +@Entity('tokenGame') +export class TokenGame { + + @PrimaryGeneratedColumn() + id: number; + @Column() + playerOneUsername : string + @Column({nullable: true}) + playerTwoUsername : string + @Column() + gameOptions : number + @Column() + isGameIsWithInvitation : boolean + @Column({default: 0, nullable: true}) + numberOfRegisteredUser : number + @Column({default : false}) + isSecondUserAcceptedRequest : boolean + @Column() + token : string +} diff --git a/srcs/requirements/nestjs/api_back/src/game/entity/user.entity.ts b/srcs/requirements/nestjs/api_back/src/game/entity/user.entity.ts deleted file mode 100644 index 6c45d3a5..00000000 --- a/srcs/requirements/nestjs/api_back/src/game/entity/user.entity.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; - - - -@Entity('gameParty') -export class gameParty { - - @PrimaryGeneratedColumn() - id: number; - - @Column() - playerOne: string - - @Column() - playerTwo: string - - @Column() - resultOfTheMatch: string - - @Column() - gameServerIdOfTheMatch: string -} diff --git a/srcs/requirements/nestjs/api_back/src/game/game.controller.ts b/srcs/requirements/nestjs/api_back/src/game/game.controller.ts index d86df072..b393eaf5 100644 --- a/srcs/requirements/nestjs/api_back/src/game/game.controller.ts +++ b/srcs/requirements/nestjs/api_back/src/game/game.controller.ts @@ -1,4 +1,104 @@ -import { Controller } from '@nestjs/common'; +import { Body, Controller, Get, HttpException, HttpStatus, Post, Req, Res, UseGuards } from '@nestjs/common'; +import { AuthenticateGuard, TwoFactorGuard } from 'src/auth/42/guards/42guards'; +import { User } from 'src/users/entities/user.entity'; +import { Response } from 'express'; +import { CreateGameDto } from './dto/createGame.dto'; +import { GrantTicketDto } from './dto/grantTicket.dto'; +import { UpdateGameDto } from './dto/updateGame.dto'; +import { ValidateTicketDto } from './dto/validateTicket.dto'; +import { GameService } from './game.service'; @Controller('game') -export class GameController {} +export class GameController { + constructor (private readonly gameService : GameService) { } + + + @Get('match/all') + @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) + async getMatchesForSpectator() + { + return this.gameService.getMatchesForSpectator(); + } + + @Get('ranking') + @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) + async getRankingForAllUsers(@Req() req) + { + const currentUser : User = req.user + return this.gameService.getRankingForAllUsers(currentUser); + } + + @Post('ticket') + @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) + async grantTicket(@Req() req, @Body() grantTicketDto : GrantTicketDto, @Res() res : Response) + { + const user : User = req.user + if (grantTicketDto.playerOneUsername != user.username) + return res.status(HttpStatus.BAD_REQUEST).json({message : 'You can\'t grant a ticket to another user'}); + return this.gameService.generateToken(user, grantTicketDto, res); + } + + @Post('decline') + @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) + async declineInvitation(@Body('token') token, @Req() req, @Res() res : Response) + { + const user : User = req.user; + return this.gameService.declineInvitation(user, token, res); + } + + @Post('accept') + @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) + async acceptInvitation(@Body('token') token, @Req() req, @Res() res : Response) + { + const user : User = req.user; + return this.gameService.acceptInvitation(user, token, res); + } + + + @Get('invitations') + @UseGuards(AuthenticateGuard) + @UseGuards(TwoFactorGuard) + async findInvitations(@Req() request, @Res() res : Response) + { + const user : User = request.user; + return this.gameService.findInvitations(user, res); + } + + // + //N'est valable que pour le game-serveur. + @Post('gameserver/validate') + async validateTicket(@Body() validateTicketDto : ValidateTicketDto, @Req() request) + { + if (await this.gameService.validateToken(validateTicketDto) === false) + return new HttpException("The token is not valid", HttpStatus.NOT_FOUND); + console.log("200 retourné côté nest") + return HttpStatus.OK; + } + + @Post('gameserver/creategame') + async createGame(@Body() creategameDto : CreateGameDto) + { + console.log("On est dans create game") + console.log(creategameDto) + return this.gameService.createGame(creategameDto); + } + + @Post('gameserver/updategame') + async updateGame(@Body() updateGameDto : UpdateGameDto) + { + console.log("On est dans update game") + console.log(updateGameDto) + return this.gameService.updateGame(updateGameDto); + } + + @Post('gameserver/destroysession') + async destroySession(@Body('token') token) + { + return this.gameService.destroySession(token); + } +} diff --git a/srcs/requirements/nestjs/api_back/src/game/game.module.ts b/srcs/requirements/nestjs/api_back/src/game/game.module.ts index 17a50c06..e834599f 100644 --- a/srcs/requirements/nestjs/api_back/src/game/game.module.ts +++ b/srcs/requirements/nestjs/api_back/src/game/game.module.ts @@ -1,9 +1,17 @@ import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Friendship } from 'src/friendship/entities/friendship.entity'; +import { FriendshipService } from 'src/friendship/friendship.service'; +import { User } from 'src/users/entities/user.entity'; +import { UsersService } from 'src/users/users.service'; +import { Game } from './entity/game.entity'; +import { TokenGame } from './entity/tokenGame.entity'; import { GameController } from './game.controller'; import { GameService } from './game.service'; @Module({ - controllers: [GameController], - providers: [GameService] + imports: [TypeOrmModule.forFeature([TokenGame, User, Game, Friendship])], + controllers: [GameController], + providers: [GameService, UsersService, FriendshipService] }) export class GameModule {} diff --git a/srcs/requirements/nestjs/api_back/src/game/game.service.spec.ts b/srcs/requirements/nestjs/api_back/src/game/game.service.spec.ts index f4a1db7e..d91fa17d 100644 --- a/srcs/requirements/nestjs/api_back/src/game/game.service.spec.ts +++ b/srcs/requirements/nestjs/api_back/src/game/game.service.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { GameService } from './game.service'; +// import { Test, TestingModule } from '@nestjs/testing'; +// // import { GameService } from './game.service'; -describe('GameService', () => { - let service: GameService; +// describe('GameService', () => { +// let service: GameService; - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [GameService], - }).compile(); +// beforeEach(async () => { +// const module: TestingModule = await Test.createTestingModule({ +// providers: [GameService], +// }).compile(); - service = module.get(GameService); - }); +// service = module.get(GameService); +// }); - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); +// it('should be defined', () => { +// expect(service).toBeDefined(); +// }); +// }); diff --git a/srcs/requirements/nestjs/api_back/src/game/game.service.ts b/srcs/requirements/nestjs/api_back/src/game/game.service.ts index 18ca270d..aa98d202 100644 --- a/srcs/requirements/nestjs/api_back/src/game/game.service.ts +++ b/srcs/requirements/nestjs/api_back/src/game/game.service.ts @@ -1,4 +1,299 @@ -import { Injectable } from '@nestjs/common'; +import { HttpException, HttpStatus, Injectable, Res } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { createCipheriv, randomBytes, scrypt } from 'crypto'; +import { User } from 'src/users/entities/user.entity'; +import { Repository } from 'typeorm'; +import { promisify } from 'util'; +import { Response } from 'express'; +import { GrantTicketDto } from './dto/grantTicket.dto'; +import { Game } from './entity/game.entity'; +import { ValidateTicketDto } from './dto/validateTicket.dto'; +import { TokenGame } from './entity/tokenGame.entity'; +import { UsersService } from 'src/users/users.service'; +import { CreateGameDto } from './dto/createGame.dto'; +import { UpdateGameDto } from './dto/updateGame.dto'; +import { FriendshipService } from 'src/friendship/friendship.service'; +import { STATUS } from 'src/common/constants/constants'; @Injectable() -export class GameService {} +export class GameService { + constructor ( + @InjectRepository(Game) + private readonly gameRepository : Repository, + @InjectRepository(User) + private readonly userRepository : Repository, + @InjectRepository(TokenGame) + private readonly tokenGameRepository : Repository, + private readonly userService : UsersService, + private readonly friendShipService : FriendshipService + ) { } + + async getMatchesForSpectator() { + const games = await this.gameRepository.createQueryBuilder("game") + .where('game.isMatchIsFinished = :isMatchIsFinished', {isMatchIsFinished : false}) + .getMany(); + const gamesToReturn : Partial[] = [] + for (const game of games) + { + gamesToReturn.push({gameServerIdOfTheMatch : game.gameServerIdOfTheMatch, + gameOptions : game.gameOptions, playerOneUsername : game.playerOneUsername, + playerTwoUsername : game.playerTwoUsername}) + console.log("Is match is finished : " + game.isMatchIsFinished) + } + return gamesToReturn; + } + + async getRankingForAllUsers(currentUser : User) { + const users = await this.userRepository.createQueryBuilder("user") + .leftJoinAndSelect("user.stats", "stats") + .orderBy('stats.winGame', "DESC") + .getMany(); + const partialUser : Partial[] = [] + for (const user of users) + { + if (await this.friendShipService.findIfUserIsBlockedOrHasBlocked(currentUser.id, user.id) === false) + partialUser.push({username : user.username, stats : user.stats }) + } + console.log(...partialUser) + return partialUser; + } + + + async encryptToken(toEncrypt : string) : Promise { + const iv = randomBytes(16); + const password = process.env.TICKET_FOR_PLAYING_GAME_SECRET + new Date(); + const key = (await promisify(scrypt)(password, 'salt', 32)) as Buffer; + const cipher = createCipheriv('aes-256-ctr', key, iv); + const encryptedText = Buffer.concat([ + cipher.update(toEncrypt), + cipher.final(), + ]); + const encryptedTextToReturn = encryptedText.toString('base64'); + return encryptedTextToReturn + } + + async deleteToken(user : User){ + const tokenGame = await this.tokenGameRepository.createQueryBuilder('tokengame') + .where('tokengame.playerTwoUsername = :playerTwoUsername', {playerTwoUsername : user.username}) + .orWhere('tokengame.playerOneUsername = :playerOneUsername', {playerOneUsername : user.username}) + .getMany(); + if (tokenGame) + return this.tokenGameRepository.remove(tokenGame); + } + + async generateToken(user : User, grantTicketDto : GrantTicketDto, @Res() res : Response) + { + console.log(user.status); + if (user.status === STATUS.IN_POOL || user.status === STATUS.IN_GAME) + { + await this.deleteToken(user); + user.status = STATUS.CONNECTED; + this.userRepository.save(user); + } + if (grantTicketDto.isGameIsWithInvitation === true) + { + const secondUser : Partial = await this.userService.findOne(grantTicketDto.playerTwoUsername) + if (!secondUser || secondUser.username === user.username) + return res.status(HttpStatus.NOT_FOUND).json({message : "User not found OR you want to play with yourself."}); + const encryptedTextToReturn = await this.encryptToken(user.username + '_' + secondUser.username + '_' + + grantTicketDto.gameOptions + '_' + grantTicketDto.isGameIsWithInvitation + '_' + new Date()) + const tok = this.tokenGameRepository.create(grantTicketDto); + tok.isSecondUserAcceptedRequest = false; + tok.numberOfRegisteredUser = 0; + tok.token = encryptedTextToReturn; + this.tokenGameRepository.save(tok); + this.userService.updateStatus(user.id, "In Pool") + return res.status(HttpStatus.OK).json({ token : encryptedTextToReturn }); + } + else if (grantTicketDto.isGameIsWithInvitation === false) { + const encryptedTextToReturn = await this.encryptToken(user.username + '_' + + grantTicketDto.gameOptions + '_' + grantTicketDto.isGameIsWithInvitation + '_' + new Date()) + const tok = this.tokenGameRepository.create(grantTicketDto); + tok.numberOfRegisteredUser = 0; + tok.token = encryptedTextToReturn; + this.tokenGameRepository.save(tok); + this.userService.updateStatus(user.id, "In Pool") + return res.status(HttpStatus.OK).json({ token : encryptedTextToReturn }); + } + return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({message : "Internal Server Error"}); + } + + async validateToken(validateTicketDto : ValidateTicketDto) { + if (validateTicketDto.isGameIsWithInvitation === true) + { + const tokenGame : TokenGame = await this.tokenGameRepository.createQueryBuilder('tokengame') + .where('tokengame.playerOneUsername = :playerOneUsername', {playerOneUsername : validateTicketDto.playerOneUsername}) + .andWhere('tokengame.playerTwoUsername = :playerTwoUsername', {playerTwoUsername : validateTicketDto.playerTwoUsername}) + .andWhere('tokengame.gameOptions = :gameOption', {gameOption : validateTicketDto.gameOptions}) + .andWhere('tokengame.isGameIsWithInvitation = :isGameIsWithInvitation', {isGameIsWithInvitation: true}) + .andWhere('tokengame.isSecondUserAcceptedRequest = :choice', {choice : true}) + .andWhere('tokengame.token = :token', {token : validateTicketDto.token}) + .getOne(); + if (tokenGame) + { + tokenGame.numberOfRegisteredUser++; + if (tokenGame.numberOfRegisteredUser === 2) + { + this.tokenGameRepository.remove(tokenGame) + const userOne : User = await this.userRepository.createQueryBuilder('user') + .where("user.username = :username", {username : tokenGame.playerOneUsername}) + .getOne(); + this.userService.updateStatus(userOne.id, "In Game") + const userTwo : User = await this.userRepository.createQueryBuilder('user') + .where("user.username = :username", {username : tokenGame.playerTwoUsername}) + .getOne(); + this.deleteToken(userOne) + this.deleteToken(userTwo) + this.userService.updateStatus(userTwo.id, "In Game") + } + return true; + } + } + else if (validateTicketDto.isGameIsWithInvitation === false) + { + const tokenGame : TokenGame = await this.tokenGameRepository.createQueryBuilder('tokengame') + .where('tokengame.playerOneUsername = :playerOneUsername', {playerOneUsername : validateTicketDto.playerOneUsername}) + .andWhere('tokengame.gameOptions = :gameOption', {gameOption : validateTicketDto.gameOptions}) + .andWhere('tokengame.isGameIsWithInvitation = :isGameIsWithInvitation', {isGameIsWithInvitation: false}) + .andWhere('tokengame.token = :token', {token : validateTicketDto.token}) + .getOne(); + if (tokenGame) + { + this.tokenGameRepository.remove(tokenGame) + console.log("USERNAME : " + tokenGame.playerOneUsername) + const user : User = await this.userRepository.createQueryBuilder('user') + .where("user.username = :username", {username : tokenGame.playerOneUsername}) + .getOne(); + this.userService.updateStatus(user.id, "In Game") + this.deleteToken(user) + return true; + } + } + return false; + } + + async findInvitations(user : User, @Res() res : Response) { + const game = await this.tokenGameRepository.createQueryBuilder('tokengame') + .where('tokengame.playerTwoUsername = :playerTwoUsername', {playerTwoUsername : user.username}) + .andWhere('tokengame.isGameIsWithInvitation = :invit', {invit : true}) + .andWhere('tokengame.isSecondUserAcceptedRequest = :choice', {choice : false}) + .getMany(); + if (!game) + return res.status(HttpStatus.NOT_FOUND).send({message : "No invitation found"}); + let partialGame : Partial[] = []; + for (const gameToken of game) { + partialGame.push({ + playerOneUsername : gameToken.playerOneUsername, + playerTwoUsername : gameToken.playerTwoUsername, + gameOptions : gameToken.gameOptions, + token : gameToken.token, + }); + } + return res.status(HttpStatus.OK).json(partialGame); + } + + async declineInvitation(user : User, token : string, @Res() res : Response) + { + if (user.status !== "Connected") + return res.status(HttpStatus.FORBIDDEN).json({message : "You must not be in game to decline an invitation"}); + console.log("On décline l'invitation") + const tokenGame = await this.tokenGameRepository.createQueryBuilder('tokengame') + .andWhere('tokengame.playerTwoUsername = :playerTwoUsername', {playerTwoUsername : user.username}) + .andWhere('tokengame.token = :token', {token : token}) + .getOne(); + if (tokenGame) + { + this.tokenGameRepository.remove(tokenGame); + return res.status(HttpStatus.OK).json({message : "Invitation declined."}); + } + return res.status(HttpStatus.NOT_FOUND).json({message : "No invitation found !"}); + } + + async destroySession(token : string) + { + console.log("On détruit le token et la session qui va avec") + const tokenGame = await this.tokenGameRepository.createQueryBuilder('tokengame') + .where('tokengame.token = :token', {token : token}) + .getOne(); + if (tokenGame) + { + const playerOne = await this.userRepository.findOneBy({username : tokenGame.playerOneUsername}) + const playerTwo = await this.userRepository.findOneBy({username : tokenGame.playerTwoUsername}) + if (playerOne.status !== "Disconnected") + this.userService.updateStatus(playerOne.id, "Connected") + if (playerTwo.status !== "Disconnected") + this.userService.updateStatus(playerTwo.id, "Connected") + return this.tokenGameRepository.remove(tokenGame); + } + return new HttpException("Token not found !", HttpStatus.NOT_FOUND) + } + + async acceptInvitation(user : User, token : string, @Res() res : Response) + { + if (user.status !== "Connected") + return res.status(HttpStatus.FORBIDDEN).send("") + const tokenGame = await this.tokenGameRepository.createQueryBuilder('tokenGame') + .andWhere('tokenGame.playerTwoUsername = :playerTwoUsername', {playerTwoUsername : user.username}) + .andWhere('tokenGame.token = :token', {token : token}) + .getOne(); + if (tokenGame) + { + tokenGame.isSecondUserAcceptedRequest = true; + this.tokenGameRepository.save(tokenGame) + return res.status(HttpStatus.OK).json({message : "Invitation accepted."}); + } + return res.status(HttpStatus.NOT_FOUND).json({message : "No invitation found !"}); + } + + async createGame(creategameDto : CreateGameDto) + { + if (creategameDto.playerOneUsername === "" || creategameDto.playerTwoUsername === "" + || creategameDto.playerOneUsername === creategameDto.playerTwoUsername) + return HttpStatus.INTERNAL_SERVER_ERROR + const game = this.gameRepository.create(creategameDto) + game.isMatchIsFinished = false; + this.gameRepository.save(game); + if (!game) + return HttpStatus.INTERNAL_SERVER_ERROR + console.log("200 retourné pour la création de partie") + return HttpStatus.OK + } + + async updateGame(updateGameDto : UpdateGameDto) { + console.log("Updata game" + updateGameDto) + const game = await this.gameRepository.createQueryBuilder('game') + .where("game.gameServerIdOfTheMatch = :gameServerIdOfTheMatch", {gameServerIdOfTheMatch : updateGameDto.gameServerIdOfTheMatch}) + .getOne(); + if (!game) + throw new HttpException(`The game could not be updated.`,HttpStatus.NOT_FOUND); + game.isMatchIsFinished = true; + game.playerOneUsernameResult = updateGameDto.playerOneUsernameResult + game.playerTwoUsernameResult = updateGameDto.playerTwoUsernameResult + this.gameRepository.save(game); + console.log("On a sauvegardé la partie. Game :") + console.log(game) + const playerOne = await this.userRepository.findOneBy({username : game.playerOneUsername}) + const playerTwo = await this.userRepository.findOneBy({username : game.playerTwoUsername}) + if (!playerOne || !playerTwo) + return new HttpException("Internal Server Error. Impossible to update the database", HttpStatus.INTERNAL_SERVER_ERROR); + if (game.playerOneUsernameResult === game.playerTwoUsernameResult) + { + this.userService.incrementDraws(playerOne.id) + this.userService.incrementDraws(playerTwo.id) + } + else if (game.playerOneUsernameResult < game.playerTwoUsernameResult) + { + this.userService.incrementDefeats(playerOne.id) + this.userService.incrementVictories(playerTwo.id) + } + else + { + this.userService.incrementVictories(playerOne.id) + this.userService.incrementDefeats(playerTwo.id) + } + this.userService.updateStatus(playerOne.id, "Connected") + this.userService.updateStatus(playerTwo.id, "Connected") + return HttpStatus.OK + } +} + diff --git a/srcs/requirements/nestjs/api_back/src/main.ts b/srcs/requirements/nestjs/api_back/src/main.ts index 78cb852c..e9ea8426 100644 --- a/srcs/requirements/nestjs/api_back/src/main.ts +++ b/srcs/requirements/nestjs/api_back/src/main.ts @@ -8,7 +8,7 @@ import * as connectRedis from 'connect-redis'; async function bootstrap() { const app = await NestFactory.create(AppModule, { cors: true }); - const port = process.env.PORT || 3001; + const port = process.env.PORT || 3000; const client = redis.createClient( { socket: { host: process.env.REDIS_HOST, port: parseInt(process.env.REDIS_PORT) }, @@ -50,6 +50,6 @@ async function bootstrap() { ); app.use(passport.initialize()); app.use(passport.session()); - await app.listen(port, () => { console.log(`Listening on port ${port}`); }); + await app.listen(port, () => { console.log(`Listening on port ${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}}`); }); } bootstrap(); diff --git a/srcs/requirements/nestjs/api_back/src/users/dto/update-users.dto.ts b/srcs/requirements/nestjs/api_back/src/users/dto/update-users.dto.ts index 53e00fb3..eaad2c5b 100644 --- a/srcs/requirements/nestjs/api_back/src/users/dto/update-users.dto.ts +++ b/srcs/requirements/nestjs/api_back/src/users/dto/update-users.dto.ts @@ -2,7 +2,7 @@ // et de les mettre comme optionnelles. De plus on peut hériter // des décorateurs de la classe parente (par exemple @IsString()). -import { OmitType, PartialType } from "@nestjs/mapped-types"; +import { OmitType } from "@nestjs/mapped-types"; import { CreateUsersDto } from "./create-users.dto"; export class UpdateUsersDto extends OmitType(CreateUsersDto, ['fortyTwoId', 'email', 'image_url', 'status'] as const){} diff --git a/srcs/requirements/nestjs/api_back/src/users/entities/user.entity.ts b/srcs/requirements/nestjs/api_back/src/users/entities/user.entity.ts index c00427b3..b7ed9f65 100644 --- a/srcs/requirements/nestjs/api_back/src/users/entities/user.entity.ts +++ b/srcs/requirements/nestjs/api_back/src/users/entities/user.entity.ts @@ -28,7 +28,7 @@ export class User { @Column({ nullable: true }) phone: string; - @Column({ default: 'disconnected' }) + @Column({ default: 'Disconnected' }) status: string; // @Column() diff --git a/srcs/requirements/nestjs/api_back/src/users/users.controller.ts b/srcs/requirements/nestjs/api_back/src/users/users.controller.ts index 19682e8d..2b350667 100644 --- a/srcs/requirements/nestjs/api_back/src/users/users.controller.ts +++ b/srcs/requirements/nestjs/api_back/src/users/users.controller.ts @@ -1,5 +1,5 @@ import { - Body, Controller, Delete, Get, NotFoundException, Param, Patch, Post, Query, Redirect, Req, Res, UploadedFile, UseGuards, UseInterceptors + Body, Controller, Delete, Get, NotFoundException,HttpStatus, Param, Patch, Post, Query, Redirect, Req, Res, UploadedFile, UseGuards, UseInterceptors } from '@nestjs/common'; import { FileInterceptor } from '@nestjs/platform-express'; import { Response } from 'express'; @@ -84,12 +84,9 @@ export class UsersController { @UseGuards(TwoFactorGuard) @Patch() async update(@Req() req, @Body(new ValidationPipe()) usersUpdateDto: UpdateUsersDto, @Res() response : Response) { - console.log("DANS PATCH USERS"); const user = await this.usersService.update(req.user.id, usersUpdateDto); - // const user : User = req.user; if (user.isEnabledTwoFactorAuth === false && user.isTwoFactorAuthenticated === true) this.usersService.setIsTwoFactorAuthenticatedWhenLogout(user.id); - console.log ("Enbale 2FA " + user.isEnabledTwoFactorAuth + " Is authenticated " + user.isTwoFactorAuthenticated); if (user.isEnabledTwoFactorAuth === true && user.isTwoFactorAuthenticated === false) { response.status(201).send('2FA redirect') @@ -111,9 +108,14 @@ export class UsersController { @UseGuards(TwoFactorGuard) @Post('avatar') @UseInterceptors(FileInterceptor('file', storageForAvatar)) - uploadAvatar(@UploadedFile() file, @Req() request){ + uploadAvatar(@UploadedFile() file, @Req() request, @Res() res){ const user : User = request.user; - this.usersService.updateAvatar(user.id, file.filename); + if (file) + { + this.usersService.updateAvatar(user.id, file.filename); + return res.status(HttpStatus.OK).json({message : "Avatar updated"}); + } + return res.status(HttpStatus.UNSUPPORTED_MEDIA_TYPE).json({message : "Unsupported media type. Please use a valid image file."}); } // GET http://transcendance:8080/user/avatar diff --git a/srcs/requirements/nestjs/api_back/src/users/users.service.ts b/srcs/requirements/nestjs/api_back/src/users/users.service.ts index 68b75721..0251f2e0 100644 --- a/srcs/requirements/nestjs/api_back/src/users/users.service.ts +++ b/srcs/requirements/nestjs/api_back/src/users/users.service.ts @@ -4,12 +4,9 @@ import { User } from './entities/user.entity'; import { Repository, Not } from 'typeorm'; import { CreateUsersDto } from './dto/create-users.dto'; import { UpdateUsersDto } from './dto/update-users.dto'; -import { Friendship } from '../friendship/entities/friendship.entity'; import { PaginationQueryDto } from 'src/common/dto/pagination-query.dto'; import { UserStats } from './entities/userStat.entities'; import { FriendshipService } from 'src/friendship/friendship.service'; -import { stringify } from 'querystring'; - // On va devoir sûrement trouver un moyen plus simple pour passer l'id, sûrement via des pipes // ou des interceptors, mais pour l'instant on va faire comme ça. @Injectable() @@ -86,6 +83,28 @@ export class UsersService { return partialUsers; } + // async findAbsolutelyAll() { + // // const otherUsers = await this.userRepository.find({where: {id: Not(+currentUser.id)}, order: {username: "ASC"}, skip: offset, take: limit,}); + // const otherUsers = await this.userRepository.find({order: {username: "ASC"}}); + + // let partialUsers : Partial[] = []; + + // for (const otherUser of otherUsers) { + // console.log('other user: ') + // console.log({...otherUser}) + // let tmp = await this.friendshipService.findIfUserIsBlockedOrHasBlocked(currentUser.id, otherUser.id); + // console.log('user.services findIF Blocked... : ') + // console.log(tmp) + // if (tmp === false) { + // // if (await this.friendshipService.findIfUserIsBlockedOrHasBlocked(currentUser.id, otherUser.id) === false) { + // partialUsers.push({username: otherUser.username, image_url: otherUser.image_url, status: otherUser.status, stats: otherUser.stats}); + // } + // } + // console.log('user.services findAll, partialUsers:') + // console.log({...partialUsers}) + // return partialUsers; + // } + async create(createUserDto: CreateUsersDto) { diff --git a/srcs/requirements/nginx/conf/default.conf b/srcs/requirements/nginx/conf/default.conf index bbaaa8c5..02ffec11 100644 --- a/srcs/requirements/nginx/conf/default.conf +++ b/srcs/requirements/nginx/conf/default.conf @@ -1,7 +1,7 @@ server { - listen 8080 default_server; - listen [::]:8080 default_server; - server_name transcendance; + listen 8080; + listen [::]:8080; + server_name localhost; location /api/v2 { proxy_set_header Host $host; @@ -10,6 +10,28 @@ server { proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://backend_dev:3000; } + + location /chat { + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_pass http://backend_dev:5000/chat; + } + + location /api/v2/game/gameserver { + deny all; + } + + location /pong { + proxy_pass http://game_server:8042/pong; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_set_header Host $host; + } + location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; @@ -20,10 +42,9 @@ server { } server { - listen 35729 default_server; listen [::]:35729 default_server; - server_name transcendance; + server_name localhost; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; diff --git a/srcs/requirements/nginx/conf/nginx.conf b/srcs/requirements/nginx/conf/nginx.conf new file mode 100644 index 00000000..df5a4609 --- /dev/null +++ b/srcs/requirements/nginx/conf/nginx.conf @@ -0,0 +1,37 @@ + +user nginx; +worker_processes auto; + +error_log /var/log/nginx/error.log notice; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + + #gzip on; + + include /etc/nginx/conf.d/*.conf; +} diff --git a/srcs/requirements/svelte/.dockerignore b/srcs/requirements/svelte/.dockerignore index 29c9a005..836f34cf 100644 --- a/srcs/requirements/svelte/.dockerignore +++ b/srcs/requirements/svelte/.dockerignore @@ -8,3 +8,4 @@ !api_front/*.json !api_front/*.html !api_front/*.lock +!api_front/.env diff --git a/srcs/requirements/svelte/api_front/README.md b/srcs/requirements/svelte/api_front/README.md deleted file mode 100644 index 43e08d6a..00000000 --- a/srcs/requirements/svelte/api_front/README.md +++ /dev/null @@ -1,107 +0,0 @@ -# This repo is no longer maintained. Consider using `npm init vite` and selecting the `svelte` option or — if you want a full-fledged app framework and don't mind using pre-1.0 software — use [SvelteKit](https://kit.svelte.dev), the official application framework for Svelte. - ---- - -# svelte app - -This is a project template for [Svelte](https://svelte.dev) apps. It lives at https://github.com/sveltejs/template. - -To create a new project based on this template using [degit](https://github.com/Rich-Harris/degit): - -```bash -npx degit sveltejs/template svelte-app -cd svelte-app -``` - -*Note that you will need to have [Node.js](https://nodejs.org) installed.* - - -## Get started - -Install the dependencies... - -```bash -cd svelte-app -npm install -``` - -...then start [Rollup](https://rollupjs.org): - -```bash -npm run dev -``` - -Navigate to [localhost:8080](http://localhost:8080). You should see your app running. Edit a component file in `src`, save it, and reload the page to see your changes. - -By default, the server will only respond to requests from localhost. To allow connections from other computers, edit the `sirv` commands in package.json to include the option `--host 0.0.0.0`. - -If you're using [Visual Studio Code](https://code.visualstudio.com/) we recommend installing the official extension [Svelte for VS Code](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). If you are using other editors you may need to install a plugin in order to get syntax highlighting and intellisense. - -## Building and running in production mode - -To create an optimised version of the app: - -```bash -npm run build -``` - -You can run the newly built app with `npm run start`. This uses [sirv](https://github.com/lukeed/sirv), which is included in your package.json's `dependencies` so that the app will work when you deploy to platforms like [Heroku](https://heroku.com). - - -## Single-page app mode - -By default, sirv will only respond to requests that match files in `public`. This is to maximise compatibility with static fileservers, allowing you to deploy your app anywhere. - -If you're building a single-page app (SPA) with multiple routes, sirv needs to be able to respond to requests for *any* path. You can make it so by editing the `"start"` command in package.json: - -```js -"start": "sirv public --single" -``` - -## Using TypeScript - -This template comes with a script to set up a TypeScript development environment, you can run it immediately after cloning the template with: - -```bash -node scripts/setupTypeScript.js -``` - -Or remove the script via: - -```bash -rm scripts/setupTypeScript.js -``` - -If you want to use `baseUrl` or `path` aliases within your `tsconfig`, you need to set up `@rollup/plugin-alias` to tell Rollup to resolve the aliases. For more info, see [this StackOverflow question](https://stackoverflow.com/questions/63427935/setup-tsconfig-path-in-svelte). - -## Deploying to the web - -### With [Vercel](https://vercel.com) - -Install `vercel` if you haven't already: - -```bash -npm install -g vercel -``` - -Then, from within your project folder: - -```bash -cd public -vercel deploy --name my-project -``` - -### With [surge](https://surge.sh/) - -Install `surge` if you haven't already: - -```bash -npm install -g surge -``` - -Then, from within your project folder: - -```bash -npm run build -surge public my-project.surge.sh -``` diff --git a/srcs/requirements/svelte/api_front/old_unused/App_old.svelte b/srcs/requirements/svelte/api_front/old_unused/App_old.svelte deleted file mode 100644 index 4052bae1..00000000 --- a/srcs/requirements/svelte/api_front/old_unused/App_old.svelte +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - diff --git a/srcs/requirements/svelte/api_front/old_unused/Canvas_1st_attempt.svelte b/srcs/requirements/svelte/api_front/old_unused/Canvas_1st_attempt.svelte deleted file mode 100644 index 4d3e6c26..00000000 --- a/srcs/requirements/svelte/api_front/old_unused/Canvas_1st_attempt.svelte +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - - diff --git a/srcs/requirements/svelte/api_front/old_unused/Canvas_weird_circles.svelte b/srcs/requirements/svelte/api_front/old_unused/Canvas_weird_circles.svelte deleted file mode 100644 index 330e93f7..00000000 --- a/srcs/requirements/svelte/api_front/old_unused/Canvas_weird_circles.svelte +++ /dev/null @@ -1,45 +0,0 @@ - - - diff --git a/srcs/requirements/svelte/api_front/old_unused/DisplayAUser_backup_copy.svelte b/srcs/requirements/svelte/api_front/old_unused/DisplayAUser_backup_copy.svelte deleted file mode 100644 index 85d8fe4e..00000000 --- a/srcs/requirements/svelte/api_front/old_unused/DisplayAUser_backup_copy.svelte +++ /dev/null @@ -1,112 +0,0 @@ - - -{#if user !== undefined} - -{:else} -

Sorry

-
Failed to load user {aUsername}
-{/if} - - - - \ No newline at end of file diff --git a/srcs/requirements/svelte/api_front/old_unused/FlyingPotato.svelte b/srcs/requirements/svelte/api_front/old_unused/FlyingPotato.svelte deleted file mode 100644 index 5f6b544f..00000000 --- a/srcs/requirements/svelte/api_front/old_unused/FlyingPotato.svelte +++ /dev/null @@ -1,24 +0,0 @@ - \ No newline at end of file diff --git a/srcs/requirements/svelte/api_front/old_unused/Header.svelte b/srcs/requirements/svelte/api_front/old_unused/Header.svelte deleted file mode 100644 index 3afd24fd..00000000 --- a/srcs/requirements/svelte/api_front/old_unused/Header.svelte +++ /dev/null @@ -1,124 +0,0 @@ - - - - - -
- - Potato Pong Logo - -

Potato Pong

- - -
- - \ No newline at end of file diff --git a/srcs/requirements/svelte/api_front/old_unused/Header_Multi_old.svelte b/srcs/requirements/svelte/api_front/old_unused/Header_Multi_old.svelte deleted file mode 100644 index 5439b8c9..00000000 --- a/srcs/requirements/svelte/api_front/old_unused/Header_Multi_old.svelte +++ /dev/null @@ -1,102 +0,0 @@ - - - - - -
-

- Potato Pong Logo -

- -

Potato Pong

- -
- - \ No newline at end of file diff --git a/srcs/requirements/svelte/api_front/old_unused/HomePage_old.svelte b/srcs/requirements/svelte/api_front/old_unused/HomePage_old.svelte deleted file mode 100644 index 1b861b0c..00000000 --- a/srcs/requirements/svelte/api_front/old_unused/HomePage_old.svelte +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
- - - - - {#if activeItem === 'Login'} -
- -

Login

-
-
- -
{ errors.username }
-
-
- -
{ errors.password }
-
- - - -
-
-
- {:else if activeItem = 'Create Account'} - -
- -

Create Account

-
-
- -
{ errors.username }
-
-
- -
{ errors.password }
-
- - - -
-
-
- {/if} - - -
- - -