📝 Merge branch 'master' of https://codefirst.iut.uca.fr/git/Crypteam/Cryptid into histostyle
continuous-integration/drone/push Build is passing Details

pull/97/head
Pierre Ferreira 7 months ago
commit 566856374a

@ -46,6 +46,8 @@ steps:
from_secret: SECRET_REGISTRY_USERNAME
password:
from_secret: SECRET_REGISTRY_PASSWORD
environment:
REACT_APP_BASE_PATH: "/containers/Crypteam-website"
#depends_on: [ build ]

@ -1,22 +1,32 @@
FROM node:14
# Utilisez l'image Node.js LTS comme base
FROM node:14-alpine
# Définissez le répertoire de travail dans le conteneur
WORKDIR /app
# Copiez le package.json et le package-lock.json dans le conteneur
COPY package*.json ./
# Installez les dépendances du projet
RUN npm install
# Copiez le reste des fichiers de l'application dans le conteneur
COPY . .
# Construisez l'application React
RUN npm run build
EXPOSE 80
#
# Installez express
RUN npm install express
# Utilisez l'image légère Nginx pour servir l'application construite
FROM nginx:alpine
# Copiez les fichiers construits de l'étape précédente dans le répertoire de travail de Nginx
COPY --from=0 /app/build /usr/share/nginx/html
# Copiez le script serveur personnalisé
COPY server.js .
# Copiez la configuration Nginx personnalisée
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Exposez le port 80 pour que l'application puisse être accessible
EXPOSE 80
# Commande pour démarrer le serveur personnalisé
CMD ["node", "server.js"]
# Définissez ENTRYPOINT pour démarrer Nginx lorsque le conteneur est lancé
ENTRYPOINT ["nginx", "-g", "daemon off;"]

@ -1,9 +0,0 @@
<FilesMatch "\.css$">
ForceType text/css
Header set Content-Type "text/css"
</FilesMatch>
<FilesMatch "\.js$">
ForceType application/javascript
Header set Content-Type "application/javascript"
</FilesMatch>

@ -0,0 +1,15 @@
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
error_page 404 /index.html;
location ~ /\. {
deny all;
}
}

@ -19,17 +19,13 @@
"bcrypt": "^5.1.1",
"body-parser": "^1.20.2",
"bootstrap": "^5.3.2",
"cookie-parser": "^1.4.6",
"cookie-session": "^2.0.0",
"cors": "^2.8.5",
"express": "^4.18.2",
"express-session": "^1.17.3",
"file-saver": "^2.0.5",
"jspdf": "^2.5.1",
"jszip": "^3.10.1",
"jzip": "^1.0.0",
"lodash": "^4.17.21",
"mysql": "^2.18.1",
"react": "^18.2.0",
"react-bootstrap": "^2.9.1",
"react-country-flag": "^3.1.0",
@ -51,7 +47,8 @@
"@types/file-saver": "^2.0.7",
"@types/react-router-hash-link": "^2.4.9",
"@types/uuid": "^9.0.7",
"babel-jest": "^29.7.0"
"babel-jest": "^29.7.0",
"depcheck": "^1.4.7"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@ -4550,6 +4547,12 @@
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.4.tgz",
"integrity": "sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw=="
},
"node_modules/@types/minimatch": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
"integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
"dev": true
},
"node_modules/@types/node": {
"version": "20.8.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz",
@ -4991,6 +4994,117 @@
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ=="
},
"node_modules/@vue/compiler-core": {
"version": "3.3.9",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.9.tgz",
"integrity": "sha512-+/Lf68Vr/nFBA6ol4xOtJrW+BQWv3QWKfRwGSm70jtXwfhZNF4R/eRgyVJYoxFRhdCTk/F6g99BP0ffPgZihfQ==",
"dev": true,
"dependencies": {
"@babel/parser": "^7.23.3",
"@vue/shared": "3.3.9",
"estree-walker": "^2.0.2",
"source-map-js": "^1.0.2"
}
},
"node_modules/@vue/compiler-core/node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"dev": true
},
"node_modules/@vue/compiler-dom": {
"version": "3.3.9",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.9.tgz",
"integrity": "sha512-nfWubTtLXuT4iBeDSZ5J3m218MjOy42Vp2pmKVuBKo2/BLcrFUX8nCSr/bKRFiJ32R8qbdnnnBgRn9AdU5v0Sg==",
"dev": true,
"dependencies": {
"@vue/compiler-core": "3.3.9",
"@vue/shared": "3.3.9"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.3.9",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.9.tgz",
"integrity": "sha512-wy0CNc8z4ihoDzjASCOCsQuzW0A/HP27+0MDSSICMjVIFzk/rFViezkR3dzH+miS2NDEz8ywMdbjO5ylhOLI2A==",
"dev": true,
"dependencies": {
"@babel/parser": "^7.23.3",
"@vue/compiler-core": "3.3.9",
"@vue/compiler-dom": "3.3.9",
"@vue/compiler-ssr": "3.3.9",
"@vue/reactivity-transform": "3.3.9",
"@vue/shared": "3.3.9",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.5",
"postcss": "^8.4.31",
"source-map-js": "^1.0.2"
}
},
"node_modules/@vue/compiler-sfc/node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"dev": true
},
"node_modules/@vue/compiler-sfc/node_modules/magic-string": {
"version": "0.30.5",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz",
"integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==",
"dev": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.3.9",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.9.tgz",
"integrity": "sha512-NO5oobAw78R0G4SODY5A502MGnDNiDjf6qvhn7zD7TJGc8XDeIEw4fg6JU705jZ/YhuokBKz0A5a/FL/XZU73g==",
"dev": true,
"dependencies": {
"@vue/compiler-dom": "3.3.9",
"@vue/shared": "3.3.9"
}
},
"node_modules/@vue/reactivity-transform": {
"version": "3.3.9",
"resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.9.tgz",
"integrity": "sha512-HnUFm7Ry6dFa4Lp63DAxTixUp8opMtQr6RxQCpDI1vlh12rkGIeYqMvJtK+IKyEfEOa2I9oCkD1mmsPdaGpdVg==",
"dev": true,
"dependencies": {
"@babel/parser": "^7.23.3",
"@vue/compiler-core": "3.3.9",
"@vue/shared": "3.3.9",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.5"
}
},
"node_modules/@vue/reactivity-transform/node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"dev": true
},
"node_modules/@vue/reactivity-transform/node_modules/magic-string": {
"version": "0.30.5",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz",
"integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==",
"dev": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@vue/shared": {
"version": "3.3.9",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.9.tgz",
"integrity": "sha512-ZE0VTIR0LmYgeyhurPTpy4KzKsuDyQbMSdM49eKkMnT5X4VfFBLysMzjIZhLEFQYjjOVVfbvUDHckwjDFiO2eA==",
"dev": true
},
"node_modules/@webassemblyjs/ast": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
@ -5438,6 +5552,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/array-differ": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
"integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/array-flatten": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
@ -5571,6 +5694,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/arrify": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
"integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
@ -6065,14 +6197,6 @@
"node": "*"
}
},
"node_modules/bignumber.js": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
"integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==",
"engines": {
"node": "*"
}
},
"node_modules/binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@ -6358,6 +6482,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/callsite": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
"integrity": "sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==",
"dev": true,
"engines": {
"node": "*"
}
},
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@ -6869,65 +7002,11 @@
"node": ">= 0.6"
}
},
"node_modules/cookie-parser": {
"version": "1.4.6",
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz",
"integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==",
"dependencies": {
"cookie": "0.4.1",
"cookie-signature": "1.0.6"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/cookie-parser/node_modules/cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie-session": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/cookie-session/-/cookie-session-2.0.0.tgz",
"integrity": "sha512-hKvgoThbw00zQOleSlUr2qpvuNweoqBtxrmx0UFosx6AGi9lYtLoA+RbsvknrEX8Pr6MDbdWAb2j6SnMn+lPsg==",
"dependencies": {
"cookies": "0.8.0",
"debug": "3.2.7",
"on-headers": "~1.0.2",
"safe-buffer": "5.2.1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/cookie-session/node_modules/debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dependencies": {
"ms": "^2.1.1"
}
},
"node_modules/cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
},
"node_modules/cookies": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz",
"integrity": "sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==",
"dependencies": {
"depd": "~2.0.0",
"keygrip": "~1.1.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/core-js": {
"version": "3.33.2",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.2.tgz",
@ -7570,6 +7649,67 @@
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
},
"node_modules/depcheck": {
"version": "1.4.7",
"resolved": "https://registry.npmjs.org/depcheck/-/depcheck-1.4.7.tgz",
"integrity": "sha512-1lklS/bV5chOxwNKA/2XUUk/hPORp8zihZsXflr8x0kLwmcZ9Y9BsS6Hs3ssvA+2wUVbG0U2Ciqvm1SokNjPkA==",
"dev": true,
"dependencies": {
"@babel/parser": "^7.23.0",
"@babel/traverse": "^7.23.2",
"@vue/compiler-sfc": "^3.3.4",
"callsite": "^1.0.0",
"camelcase": "^6.3.0",
"cosmiconfig": "^7.1.0",
"debug": "^4.3.4",
"deps-regex": "^0.2.0",
"findup-sync": "^5.0.0",
"ignore": "^5.2.4",
"is-core-module": "^2.12.0",
"js-yaml": "^3.14.1",
"json5": "^2.2.3",
"lodash": "^4.17.21",
"minimatch": "^7.4.6",
"multimatch": "^5.0.0",
"please-upgrade-node": "^3.2.0",
"readdirp": "^3.6.0",
"require-package-name": "^2.0.1",
"resolve": "^1.22.3",
"resolve-from": "^5.0.0",
"semver": "^7.5.4",
"yargs": "^16.2.0"
},
"bin": {
"depcheck": "bin/depcheck.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/depcheck/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/depcheck/node_modules/minimatch": {
"version": "7.4.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz",
"integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@ -7578,6 +7718,12 @@
"node": ">= 0.8"
}
},
"node_modules/deps-regex": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/deps-regex/-/deps-regex-0.2.0.tgz",
"integrity": "sha512-PwuBojGMQAYbWkMXOY9Pd/NWCDNHVH12pnS7WHqZkTSeMESe4hwnKKRp0yR87g37113x4JPbo/oIvXY+s/f56Q==",
"dev": true
},
"node_modules/dequal": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
@ -7595,6 +7741,15 @@
"npm": "1.2.8000 || >= 1.4.16"
}
},
"node_modules/detect-file": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
"integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/detect-libc": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
@ -8858,6 +9013,18 @@
"node": ">= 0.8.0"
}
},
"node_modules/expand-tilde": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
"integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
"dev": true,
"dependencies": {
"homedir-polyfill": "^1.0.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/expect": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz",
@ -9242,6 +9409,21 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/findup-sync": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz",
"integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==",
"dev": true,
"dependencies": {
"detect-file": "^1.0.0",
"is-glob": "^4.0.3",
"micromatch": "^4.0.4",
"resolve-dir": "^1.0.1"
},
"engines": {
"node": ">= 10.13.0"
}
},
"node_modules/flat-cache": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz",
@ -9860,6 +10042,18 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/homedir-polyfill": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
"integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
"dev": true,
"dependencies": {
"parse-passwd": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/hoopy": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
@ -10729,6 +10923,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-windows": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-wsl": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
@ -12992,28 +13195,12 @@
"safe-buffer": "~5.1.0"
}
},
"node_modules/jzip": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/jzip/-/jzip-1.0.0.tgz",
"integrity": "sha512-pyDHf5zvxE5DC47ftNff2AU3UdJe0TYSFki0Ji6GapuZC7p2EizIbPHV7dkLj43RPv2Vj3p1xwC11kDv6dyCrA=="
},
"node_modules/keycharm": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/keycharm/-/keycharm-0.4.0.tgz",
"integrity": "sha512-TyQTtsabOVv3MeOpR92sIKk/br9wxS+zGj4BG7CR8YbK4jM3tyIBaF0zhzeBUMx36/Q/iQLOKKOT+3jOQtemRQ==",
"peer": true
},
"node_modules/keygrip": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz",
"integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==",
"dependencies": {
"tsscmp": "1.0.6"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@ -13732,50 +13919,23 @@
"multicast-dns": "cli.js"
}
},
"node_modules/mysql": {
"version": "2.18.1",
"resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz",
"integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==",
"node_modules/multimatch": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz",
"integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==",
"dev": true,
"dependencies": {
"bignumber.js": "9.0.0",
"readable-stream": "2.3.7",
"safe-buffer": "5.1.2",
"sqlstring": "2.3.1"
"@types/minimatch": "^3.0.3",
"array-differ": "^3.0.0",
"array-union": "^2.1.0",
"arrify": "^2.0.1",
"minimatch": "^3.0.4"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mysql/node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
},
"node_modules/mysql/node_modules/readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/mysql/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/mysql/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dependencies": {
"safe-buffer": "~5.1.0"
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/mz": {
@ -14381,6 +14541,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/parse-passwd": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
"integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/parse5": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
@ -14608,6 +14777,15 @@
"node": ">=4"
}
},
"node_modules/please-upgrade-node": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
"integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
"dev": true,
"dependencies": {
"semver-compare": "^1.0.0"
}
},
"node_modules/postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
@ -16661,6 +16839,12 @@
"node": ">=0.10.0"
}
},
"node_modules/require-package-name": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz",
"integrity": "sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==",
"dev": true
},
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@ -16693,6 +16877,61 @@
"node": ">=8"
}
},
"node_modules/resolve-dir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
"integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
"dev": true,
"dependencies": {
"expand-tilde": "^2.0.0",
"global-modules": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/resolve-dir/node_modules/global-modules": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
"integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
"dev": true,
"dependencies": {
"global-prefix": "^1.0.1",
"is-windows": "^1.0.1",
"resolve-dir": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/resolve-dir/node_modules/global-prefix": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
"integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
"dev": true,
"dependencies": {
"expand-tilde": "^2.0.2",
"homedir-polyfill": "^1.0.1",
"ini": "^1.3.4",
"is-windows": "^1.0.1",
"which": "^1.2.14"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/resolve-dir/node_modules/which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dev": true,
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"which": "bin/which"
}
},
"node_modules/resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
@ -17050,6 +17289,12 @@
"node": ">=10"
}
},
"node_modules/semver-compare": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
"integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
"dev": true
},
"node_modules/semver/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@ -17550,14 +17795,6 @@
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
"integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ=="
},
"node_modules/sqlstring": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
"integrity": "sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/ssri": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
@ -18597,14 +18834,6 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"node_modules/tsscmp": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz",
"integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==",
"engines": {
"node": ">=0.6.x"
}
},
"node_modules/tsutils": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",

@ -1,6 +1,7 @@
{
"name": "cryptide",
"version": "1.0.0",
"homepage": "/containers/Crypteam-website/",
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.4.2",
"@fortawesome/free-regular-svg-icons": "^6.4.2",
@ -13,17 +14,13 @@
"bcrypt": "^5.1.1",
"body-parser": "^1.20.2",
"bootstrap": "^5.3.2",
"cookie-parser": "^1.4.6",
"cookie-session": "^2.0.0",
"cors": "^2.8.5",
"express": "^4.18.2",
"express-session": "^1.17.3",
"file-saver": "^2.0.5",
"jspdf": "^2.5.1",
"jszip": "^3.10.1",
"jzip": "^1.0.0",
"lodash": "^4.17.21",
"mysql": "^2.18.1",
"react": "^18.2.0",
"react-bootstrap": "^2.9.1",
"react-country-flag": "^3.1.0",
@ -69,7 +66,8 @@
"@types/file-saver": "^2.0.7",
"@types/react-router-hash-link": "^2.4.9",
"@types/uuid": "^9.0.7",
"babel-jest": "^29.7.0"
"babel-jest": "^29.7.0",
"depcheck": "^1.4.7"
},
"babel": {
"presets": [

@ -8,10 +8,16 @@ const port = process.env.PORT || 80;
app.use(express.static(path.join(__dirname, 'build')));
// Définir le type MIME pour les fichiers JavaScript
app.use('*.js', (req, res, next) => {
app.use('/static/js', (req, res, next) => {
res.type('application/javascript; charset=utf-8');
next();
});
}, express.static(path.join(__dirname, 'build/static/js')));
// Définir le type MIME pour les fichiers CSS
app.use('/static/css', (req, res, next) => {
res.type('text/css; charset=utf-8');
next();
}, express.static(path.join(__dirname, 'build/static/css')));
// Route par défaut pour servir l'application React
app.get('*', (req, res) => {
@ -21,4 +27,5 @@ app.get('*', (req, res) => {
// Démarrer le serveur
app.listen(port, () => {
console.log(`Serveur en cours d'exécution sur le port ${port}`);
console.log(path.join(__dirname, 'build'))
});

@ -0,0 +1,181 @@
const bcrypt = require('bcrypt');
const path = require('path');
const DatabaseService = require(path.resolve(__dirname, '../services/DatabaseService.js'));
const UserService = require(path.resolve(__dirname, '../services/UserService.js'));
class AuthController {
static async signUp(req, res) {
const databaseService = new DatabaseService();
const pseudo = req.body.pseudo;
const date = new Date();
const hour = date.getHours();
const minutes = date.getMinutes();
try {
await databaseService.connect();
// Vérifier que le pseudo n'existe pas déjà
const verif = await databaseService.getUserByPseudo(pseudo);
if (verif) {
res.status(400).json({ error: 'Le pseudo est déjà utilisé.' });
return;
}
// Créer un nouvel utilisateur
const currentUser = await UserService.createUser(req.body);
const insertedUser = await databaseService.insertUser(currentUser);
const user = await databaseService.getUserByPseudo(pseudo);
console.log("[" + hour + ":" + minutes + "] " + user.pseudo + " have been registered.");
res.status(201).json({ message: 'Inscription réussie', user: insertedUser});
}
catch (error) {
// Gérer les erreurs
console.error(error);
res.status(500).json({ error: 'Erreur lors de l\'inscription.' });
}
finally {
await databaseService.disconnect();
}
}
static async signIn(req, res) {
const databaseService = new DatabaseService();
const date = new Date();
const hour = date.getHours();
const minutes = date.getMinutes();
try{
await databaseService.connect();
// Vérifier que le pseudo existe
const pseudo = req.body.pseudo;
const user = await databaseService.getUserByPseudo(pseudo);
if (!user) {
res.status(400).json({ error: 'Le pseudo n\'existe pas.' });
return;
}
// Vérifier que le mot de passe est correct
const password = req.body.password;
const validPassword = await bcrypt.compare(password, user.password);
if (!validPassword) {
res.status(400).json({ error: 'Le mot de passe est incorrect.' });
return;
}
// Stocker l'utilisateur dans la session)
req.session.user = user;
// Envoyer une réponse réussie
console.log("[" + hour + ":" + minutes + "] " + user.pseudo + " have been connected.");
res.status(200).json({ message: 'Connexion réussie', user: user });
}
catch(error){
// Gérer les erreurs
console.error(error);
res.status(500).json({ error: 'Erreur lors de la connexion.' });
}
finally{
await databaseService.disconnect();
}
}
static async logout(req, res) {
const pseudo = req.session.user.pseudo;
const date = new Date();
const hour = date.getHours();
const minutes = date.getMinutes();
// Détruire la session pour déconnecter l'utilisateur
req.session.destroy((err) => {
if (err) {
console.error(err);
res.status(500).json({ error: 'Erreur lors de la déconnexion.' });
} else {
console.log("[" + hour + ":" + minutes + "] " + pseudo + " have been disconnected.");
res.status(200).json({ message: 'Déconnexion réussie' });
}
});
}
static async delAccount(req, res){
const db = new DatabaseService();
try{
await db.connect();
const user = await db.getUserByPseudo(req.body.pseudo);
if(!user){
res.status(400).json({ error: 'Le pseudo n\'existe pas.' });
return;
}
await db.deleteUser(user.idUser);
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la supression du compte.' });
}
finally{
db.disconnect();
}
}
static async validatePassword(req, res){
const db = new DatabaseService();
try{
await db.connect();
const user = await db.getUserByPseudo(req.body.pseudo);
if(!user){
res.status(400).json({ error: 'Le pseudo n\'existe pas.' });
return;
}
const password = req.body.password;
const validPassword = await bcrypt.compare(password, user.password);
if(!validPassword){
res.status(400).json({ error: 'Le mot de passe est incorrect.' });
return;
}
res.status(200).json({ message: 'Mot de passe correct.' });
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la vérification du mot de passe.' });
}
finally{
db.disconnect();
}
}
static async updatePassword(req, res){
const db = new DatabaseService();
try{
await db.connect();
const user = await db.getUserByPseudo(req.body.pseudo);
if(!user){
res.status(400).json({ error: 'Le pseudo n\'existe pas.' });
return;
}
const hashedPassword = await bcrypt.hash(req.body.newPassword, 10);
await db.updatePassword(user.idUser, hashedPassword);
res.status(200).json({ message: 'Mot de passe mis à jour.' });
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la mise à jour du mot de passe.' });
}
finally{
db.disconnect();
}
}
}
module.exports = AuthController;

@ -0,0 +1,237 @@
const path = require('path');
const DatabaseService = require(path.resolve(__dirname, '../services/DatabaseService'));
const ENIGME_FACILE = "enigme_facile";
const ENIGME_MOYEN = "enigme_moyenne";
const ENIGME_DIFFICILE = "enigme_difficile";
class SessionController {
static async getUserInformation(req, res) {
const db = new DatabaseService();
const date = new Date();
const hour = date.getHours();
const minutes = date.getMinutes();
try{
await db.connect();
if (!req.session.user) {
res.status(200).json({ error: "true", message: 'User not found' });
return;
}
// Récupérer les stats mastermind de l'utilisateur
let nbGamesMM = await db.getNbGamesMastermindByUserId(req.session.user.idUser);
nbGamesMM = nbGamesMM.nbGames || 0;
let bestScoreMM = await db.getBestScoreMastermindByUserId(req.session.user.idUser);
bestScoreMM = bestScoreMM.bestScore || 0;
let avgNbTryMM = await db.getAvgNbTryMastermindByUserId(req.session.user.idUser);
avgNbTryMM = avgNbTryMM.avgNbTry || 0;
req.session.user.mastermindStats = {nbGames: nbGamesMM,
bestScore: bestScoreMM,
avgNbTry: avgNbTryMM};
// Récupérer les stats enigme facile
let nbGamesEF = await db.getNbGamesEnigmeByUserId(req.session.user.idUser, ENIGME_FACILE);
nbGamesEF = nbGamesEF.nbGames || 0;
let nbWinsEF = await db.getNbWinsEnigmeByUserId(req.session.user.idUser, ENIGME_FACILE);
nbWinsEF = nbWinsEF.nbWins || 0;
let ratioEF = (nbWinsEF.nbWins / nbGamesEF.nbGames) * 100 || 0;
let bestTimeEF = await db.getBestTimeEnigmeByUserId(req.session.user.idUser, ENIGME_FACILE);
bestTimeEF = bestTimeEF.bestTime || 0;
let avgTimeEF = await db.getAvgTimeEnigmeByUserId(req.session.user.idUser, ENIGME_FACILE);
avgTimeEF = avgTimeEF.avgTime || 0;
req.session.user.easyEnigmaStats = {nbGames: nbGamesEF,
nbWins: nbWinsEF,
ratio: ratioEF,
bestTime: bestTimeEF,
avgTime: avgTimeEF};
// Récupérer les stats enigme moyenne
let nbGamesEM = await db.getNbGamesEnigmeByUserId(req.session.user.idUser, ENIGME_MOYEN);
nbGamesEM = nbGamesEM.nbGames || 0;
let bestScoreEM = await db.getBestScoreEnigmeByUserId(req.session.user.idUser, ENIGME_MOYEN);
bestScoreEM = bestScoreEM.bestScore || 0;
let avgNbTryEM = await db.getAvgScoreEnigmeByUserId(req.session.user.idUser, ENIGME_MOYEN);
avgNbTryEM = avgNbTryEM.avgScore || 0;
req.session.user.mediumEnigmaStats = {nbGames: nbGamesEM,
bestScore: bestScoreEM,
avgNbTry: avgNbTryEM};
// Récupérer les stats enigme difficile
let nbGamesED = await db.getNbGamesEnigmeByUserId(req.session.user.idUser, ENIGME_DIFFICILE);
nbGamesED = nbGamesED.nbGames || 0;
let nbWinsED = await db.getNbWinsEnigmeByUserId(req.session.user.idUser, ENIGME_DIFFICILE);
nbWinsED = nbWinsED.nbWins || 0;
let ratioED = (nbWinsED.nbWins / nbGamesED.nbGames) * 100 || 0;
let bestTimeED = await db.getBestTimeEnigmeByUserId(req.session.user.idUser, ENIGME_DIFFICILE);
bestTimeED = bestTimeED.bestTime || 0;
let avgTimeED = await db.getAvgTimeEnigmeByUserId(req.session.user.idUser, ENIGME_DIFFICILE);
avgTimeED = avgTimeED.avgTime || 0;
req.session.user.hardEnigmaStats = {nbGames: nbGamesED,
nbWins: nbWinsED,
ratio: ratioED,
bestTime: bestTimeED,
avgTime: avgTimeED};
// Récupérer les stats en ligne de l'utilisateur
let nbGamesOL = await db.getNbGamesOnlineByUserId(req.session.user.idUser);
nbGamesOL = nbGamesOL.nbGames || 0;
let nbWinsOL = await db.getNbWinsOnlineByUserId(req.session.user.idUser);
nbWinsOL = nbWinsOL.nbWins || 0;
let ratioOL = (nbWinsOL.nbWins / nbGamesOL.nbGames) * 100 || 0;
req.session.user.onlineStats = {nbGames: nbGamesOL,
nbWins: nbWinsOL,
ratio: ratioOL};
console.log("[" + hour + ":" + minutes + "] " + req.session.user.pseudo + " have a session.");
res.status(200).json({ user: req.session.user });
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la récupération de l\'utilisateur.' });
}
finally{
await db.disconnect();
}
}
static async UpdatePseudo(req, res){
const db = new DatabaseService();
try{
await db.connect();
const user = await db.getUserByPseudo(req.body.pseudo);
console.log("utilisateur" + user.idUser + " pseudo" + user.pseudo)
if (!user) {
res.status(200).json({ error: "true", message: 'User not found' });
return;
}
await db.updatePseudo(user.idUser, req.body.newPseudo); //* update
const updatedUser = await db.getUserByPseudo(req.body.newPseudo);
console.log("updaetdutilisateur" + updatedUser.idUser + " pseudo" + updatedUser.pseudo)
req.session.user.pseudo = updatedUser.pseudo;
console.log("req.session.user.pseudo" + req.session.user.pseudo)
res.status(200).json({ user: req.session.user }); //verif rep
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la modification du pseudo de l\'utilisateur.' });
}
finally{
await db.disconnect();
}
}
static async addMastermindStats(req, res){
const db = new DatabaseService();
try{
await db.connect();
const user = await db.getUserByPseudo(req.body.pseudo);
if (!user) {
res.status(200).json({ error: "true", message: 'User not found' });
return;
}
await db.addMastermindStats(user.idUser, req.body.score, req.body.time);
res.status(200).json({ user: req.session.user }); //verif rep
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la modification des stats mastermind de l\'utilisateur.' });
}
finally{
await db.disconnect();
}
}
static async addEasyEnigmaStats(req, res){
const db = new DatabaseService();
try{
await db.connect();
const user = await db.getUserByPseudo(req.body.pseudo);
if (!user) {
res.status(200).json({ error: "true", message: 'User not found' });
return;
}
await db.addEasyEnigmaStats(user.idUser, ENIGME_FACILE, req.body.win, req.body.time);
res.status(200).json({ user: req.session.user }); //verif rep
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la modification des stats de l\'énigme facile de l\'utilisateur.' });
}
finally{
await db.disconnect();
}
}
// static async addMediumEnigmaStats(req, res)
static async addHardEnigmaStats(req, res){
const db = new DatabaseService();
try{
await db.connect();
const user = await db.getUserByPseudo(req.body.pseudo);
if (!user) {
res.status(200).json({ error: "true", message: 'User not found' });
return;
}
await db.addHardEnigmaStats(user.idUser, ENIGME_DIFFICILE, req.body.win, req.body.time);
res.status(200).json({ user: req.session.user }); //verif rep
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la modification des stats de l\'énigme difficile de l\'utilisateur.' });
}
finally{
await db.disconnect();
}
}
static async addOnlineStats(req, res){
const db = new DatabaseService();
try{
await db.connect();
const user = await db.getUserByPseudo(req.body.pseudo);
if (!user) {
res.status(200).json({ error: "true", message: 'User not found' });
return;
}
await db.addOnlineStats(user.idUser, req.body.win, req.body.time);
res.status(200).json({ user: req.session.user }); //verif rep
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la modification des stats en ligne de l\'utilisateur.' });
}
finally{
await db.disconnect();
}
}
}
module.exports = SessionController;

@ -8,13 +8,16 @@ router.post('/auth/signup', AuthController.signUp);
router.post('/auth/signin', AuthController.signIn);
router.delete('/auth/logout', AuthController.logout)
router.delete('/auth/delAccount', AuthController.delAccount)
router.put('/session/updateMDP', AuthController.UpdateMDP);
router.post('/auth/validatePassword', AuthController.validatePassword);
router.put('/auth/updatePassword', AuthController.updatePassword);
// Routes pour les sessions
router.get('/session', SessionController.getUserInformation);
router.post('/session/addMastermindStats', SessionController.addMastermindStats);
router.post('/session/addEasyEnigmaStats', SessionController.addEasyEnigmaStats);
// router.post('/session/addMediumEnigmaStats', SessionController.addMediumEnigmaStats);
router.post('/session/addHardEnigmaStats', SessionController.addHardEnigmaStats);
router.post('/session/addOnlineStats', SessionController.addOnlineStats);
router.put('/session/updatePseudo', SessionController.UpdatePseudo);
router.put('/session/updateSoloStats', SessionController.updateSoloStats);
router.put('/session/updateOnlineStats', SessionController.updateOnlineStats);
module.exports = router;

@ -3,8 +3,9 @@ const session = require('express-session');
const cors = require('cors');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const authRoutes = require('./routes/authRoutes');
const DatabaseService = require('./services/DatabaseService');
const path = require('path');
const authRoutes = require(path.resolve(__dirname, './routes/authRoutes'));
const DatabaseService = require(path.resolve(__dirname, './services/DatabaseService'));
const app = express();

@ -0,0 +1,339 @@
const sqlite3 = require('sqlite3');
const path = require('path');
const { rejects } = require('assert');
class DatabaseService {
constructor(){
this.db_name = "socialgraph";
}
// ----------------------------------------------------
// ------------------- UTILITAIRE ---------------------
// ----------------------------------------------------
async connect(client){
const dbPath = path.resolve(__dirname, `../../../db/${this.db_name}.db`)
return new Promise((resolve, reject) => {
this.client = new sqlite3.Database(dbPath,
sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE,
(err) => {
if(err){
reject(err);
}
else{
resolve();
}
});
});
}
async disconnect(){
return new Promise((resolve, reject) => {
this.client.close((err) => {
if(err){
reject(err);
}
else{
resolve();
}
});
});
}
// ----------------------------------------------------
// ------------------- UTILISATEUR --------------------
// ----------------------------------------------------
// Récupère l'utilisateur par son id
async getUserByID(id){
return new Promise((resolve, reject) => {
this.client.get('SELECT * FROM users WHERE idUser = ?', id, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
// Récupère l'utilisateur par son pseudo
async getUserByPseudo(pseudo){
return new Promise((resolve, reject) => {
this.client.get('SELECT * FROM users WHERE pseudo = ?', pseudo, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
// insère un utilisateur dans la base de données
async insertUser(user) {
return new Promise((resolve, reject) => {
const { pseudo, password } = user;
this.client.run('INSERT INTO users (pseudo, password) VALUES (?, ?)', [pseudo, password], (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
}
async deleteUser(userId){
return new Promise((resolve, reject) => {
this.client.run('DELETE FROM users WHERE idUser=?', userId, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async updatePseudo(userId, newPseudo){
return new Promise((resolve, reject) => {
this.client.run('UPDATE users SET pseudo = ? WHERE idUser = ?', newPseudo, userId, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async updatePassword(userId, newPassword){
return new Promise((resolve, reject) => {
this.client.run('UPDATE users SET password = ? WHERE idUser = ?', newPassword, userId, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
// -------------------------------------------------------------
// ------------------- STATS MASTERMIND ------------------------
// -------------------------------------------------------------
async getNbGamesMastermindByUserId(userId){
return new Promise((resolve, reject) => {
this.client.get('SELECT COUNT(*) AS nbGames FROM games WHERE idUser = ? AND gameType = ?', userId, "mastermind", (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async getBestScoreMastermindByUserId(userId){
return new Promise((resolve, reject) => {
this.client.get('SELECT MIN(score) AS bestScore FROM games WHERE idUser = ? AND gameType = ?', userId, "mastermind", (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async getAvgNbTryMastermindByUserId(userId){
return new Promise((resolve, reject) => {
this.client.get('SELECT AVG(score) AS avgNbTry FROM games WHERE idUser = ? AND gameType = ?', userId, "mastermind", (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async addMastermindStats(userId, score, time){
return new Promise((resolve, reject) => {
this.client.run('INSERT INTO games (idUser, gameType, win, score, time) VALUES (?, ?, ?, ?, ?)', userId, "mastermind", 1, score, time, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
// -------------------------------------------------------------
// ------------------- STATS EN LIGNE --------------------------
// -------------------------------------------------------------
async getNbGamesOnlineByUserId(userId){
return new Promise((resolve, reject) => {
this.client.get('SELECT COUNT(*) AS nbGames FROM games WHERE idUser = ? AND gameType = ?', userId, "multijoueur", (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async getNbWinsOnlineByUserId(userId){
return new Promise((resolve, reject) => {
this.client.get('SELECT COUNT(*) AS nbWins FROM games WHERE idUser = ? AND gameType = ? AND win = ?', userId, "multijoueur", 1, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async addOnlineStats(userId, win, time){
return new Promise((resolve, reject) => {
this.client.run('INSERT INTO games (idUser, gameType, win, score, time) VALUES (?, ?, ?, ?, ?)', userId, "multijoueur", win, 0, time, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
// -------------------------------------------------------------
// ------------------- STATS ENIGME ----------------------------
// -------------------------------------------------------------
async getNbGamesEnigmeByUserId(userId, enigmaLevel){
return new Promise((resolve, reject) => {
this.client.get('SELECT COUNT(*) AS nbGames FROM games WHERE idUser = ? AND gameType = ?', userId, enigmaLevel, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async getNbWinsEnigmeByUserId(userId, enigmaLevel){
return new Promise((resolve, reject) => {
this.client.get('SELECT COUNT(*) AS nbWins FROM games WHERE idUser = ? AND gameType = ? AND win = ?', userId, enigmaLevel, 1, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async getBestScoreEnigmeByUserId(userId, enigmaLevel){
return new Promise((resolve, reject) => {
this.client.get('SELECT MAX(score) AS bestScore FROM games WHERE idUser = ? AND gameType = ?', userId, enigmaLevel, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async getAvgScoreEnigmeByUserId(userId, enigmaLevel){
return new Promise((resolve, reject) => {
this.client.get('SELECT AVG(score) AS avgScore FROM games WHERE idUser = ? AND gameType = ?', userId, enigmaLevel, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async getBestTimeEnigmeByUserId(userId, enigmaLevel){
return new Promise((resolve, reject) => {
this.client.get('SELECT MIN(time) AS bestTime FROM games WHERE idUser = ? AND gameType = ?', userId, enigmaLevel, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async getAvgTimeEnigmeByUserId(userId, enigmaLevel){
return new Promise((resolve, reject) => {
this.client.get('SELECT AVG(time) AS avgTime FROM games WHERE idUser = ? AND gameType = ?', userId, enigmaLevel, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async addEasyEnigmaStats(userId, enigmaLevel, win, time){
return new Promise((resolve, reject) => {
this.client.run('INSERT INTO games (idUser, gameType, win, score, time) VALUES (?, ?, ?, ?, ?)', userId, enigmaLevel, win, 0, time, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
// async addMediumEnigmaStats(userId, enigmaLevel, score)
async addHardEnigmaStats(userId, enigmaLevel, win, time){
return new Promise((resolve, reject) => {
this.client.run('INSERT INTO games (idUser, gameType, win, score, time) VALUES (?, ?, ?, ?, ?)', userId, enigmaLevel, win, 0, time, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
}
module.exports = DatabaseService;

@ -264,4 +264,4 @@ function comparePlayersByType(a, b) {
} else {
return 0;
}
}
}

@ -9,7 +9,7 @@ import { AuthProvider } from './Contexts/AuthContext';
import Home from './Pages/Home';
import Login from './Pages/LoginForm';
import SignUp from './Pages/SignUpForm';
import Play from './Pages/Play';
import NewPlay from './Pages/NewPlay';
import Profile from './Pages/Profile';
import Lobby from './Pages/Lobby';
import InGame from './Pages/InGame';
@ -22,9 +22,6 @@ import Lobbies from './Pages/Lobbies';
/* Component */
import AppNavbar from './Components/NavBar';
/* service */
import SessionService from './services/SessionService';
/* nav */
import { BrowserRouter, Route, Routes, useLocation } from "react-router-dom";
@ -44,7 +41,8 @@ import messagesEn from './Translations/en.json';
/* Gestion d' erreur */
import ErrorBoundary from './Error/ErrorBoundary';
import ErrorPage from './Error/ErrorPage';
import NewPlay from './Pages/NewPlay';
const basePath = process.env.REACT_APP_BASE_PATH || '';
const messages = {
fr: messagesFr,
@ -62,9 +60,11 @@ function App() {
setLocale(newLocale);
};
console.log(basePath)
//const location = useLocation();
const hasNavbarVisible = ["/", "/login", "/signup", "/play", "/lobby", "/endgame", "/deduc"]//.includes(window.location.pathname);
const hasNavbarVisible = [basePath + "/", basePath + "/login", basePath + "/signup", basePath + "/play", basePath + "/lobby", basePath + "/endgame", basePath + "/deduc"]//.includes(window.location.pathname);
return (
@ -77,17 +77,18 @@ function App() {
<BrowserRouter>
{hasNavbarVisible && <AppNavbar changeLocale={changeLocale} />}
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<SignUp />} />
<Route path="/play" element={<NewPlay/>} />
<Route path="/lobby" element={<Lobby/>} />
<Route path="/endgame" element={<EndGame/>} />
<Route path="/game" element={<InGame locale={locale} changeLocale={changeLocale}/>}/>
<Route path="/info" element={<InfoPage locale={locale} changeLocale={changeLocale}/>} />
<Route path="/deduc" element={<DeducGrid/>} />
<Route path="/profile" element={<Profile/>} />
<Route path="/join" element={<Lobbies/>}/>
<Route path={`${basePath}/`} element={<NewPlay/>} />
<Route path={`${basePath}/login`} element={<Login />} />
<Route path={`${basePath}/signup`} element={<SignUp />} />
<Route path={`${basePath}/presentation`} element={<Home />} />
<Route path={`${basePath}/lobby`} element={<Lobby/>} />
<Route path={`${basePath}/endgame`} element={<EndGame/>} />
<Route path={`${basePath}/game`} element={<InGame locale={locale} changeLocale={changeLocale}/>}/>
<Route path={`${basePath}/info`} element={<InfoPage locale={locale} changeLocale={changeLocale}/>} />
<Route path={`${basePath}/deduc`} element={<DeducGrid/>} />
<Route path={`${basePath}/profile`} element={<Profile/>} />
<Route path={`${basePath}/join`} element={<Lobbies/>}/>
{/* <Route path="/solo" element={<SoloGame locale={locale} changeLocale={changeLocale} />}/> */}
<Route path="*" element={<ErrorPage code="404" msg='not found' />} /> {/* page 404 */}

@ -67,6 +67,8 @@ let cptBug = 0
let cptUseEffect = 0
let testPlayers: Player[] = []
const basePath = process.env.REACT_APP_BASE_PATH || '';
const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleShowTurnBar, handleTurnBarTextChange, playerTouched, setPlayerTouched, changecptTour, solo, isDaily, isEasy, addToHistory, showLast, setNetwork, setNetworkEnigme, setPlayerIndex, askedWrong, setAskedWrong, importToPdf, setImportToPdf}) => {
let cptTour: number = 0
@ -779,13 +781,11 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
// console.log("nbGames: " + user.onlineStats.nbGames + " nbWins: " + user.onlineStats.nbWins);
if(winner.id === currentPlayer.id){
// Ajouter une victoire
user.onlineStats.nbWins = null ? user.onlineStats.nbWins = 1 : user.onlineStats.nbWins += 1;
}
// Update les stats
user.onlineStats.nbGames = null ? user.onlineStats.nbGames = 1 : user.onlineStats.nbGames += 1;
user.onlineStats.ratio = user.onlineStats.nbWins / user.onlineStats.nbGames;
manager.userService.updateOnlineStats(user.pseudo, user.onlineStats.nbGames, user.onlineStats.nbWins, user.onlineStats.ratio);
manager.userService.addOnlineStats(user.pseudo, 1, elapsedTime);
}
else{
manager.userService.addOnlineStats(user.pseudo, 0, elapsedTime);
}
}
else{
console.error("User not found");
@ -811,7 +811,7 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
socket.off("put imossible grey")
socket.off("who plays")
navigate("/endgame")
navigate(`${basePath}/endgame`)
}
}
})
@ -996,21 +996,31 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
endgame = true
try{
if(user && user.soloStats){
user.soloStats.nbGames = null ? user.soloStats.nbGames = 1 : user.soloStats.nbGames += 1;
if(cptTour < user.soloStats.bestScore || user.soloStats.bestScore == 0 || user.soloStats.bestScore == null){
user.soloStats.bestScore = cptTour;
if(user && isLoggedIn){
if(solo){
if(isDaily){
// TODO: verif difficulté et add les stats
// TODO: verif pour facile et difficile, si réussi en one shot ou non
if(isEasy){
manager.userService.addEasyEnigmaStats(user.pseudo, 1, elapsedTime);
}
else{
manager.userService.addHardEnigmaStats(user.pseudo, 1, elapsedTime);
}
}
else{
// add stats mastermind
if(user && user.mastermindStats){
manager.userService.addMastermindStats(user.pseudo, cptTour, elapsedTime);
}
}
}
user.soloStats.avgNbTry = (user.soloStats.avgNbTry * (user.soloStats.nbGames - 1) + cptTour) / user.soloStats.nbGames;
manager.userService.updateSoloStats(user.pseudo, user.soloStats.nbGames, user.soloStats.bestScore, user.soloStats.avgNbTry);
}
}
catch(error){
console.log(error);
}
navigate("/endgame?solo=true&daily=" + isDaily)
navigate(`${basePath}/endgame?solo=true+${isDaily}`)
}
}

@ -20,6 +20,8 @@ interface LobbyContainerProps {
//? mettre un "nbplayermax" si le nombre de joueur max peut etre fixé ?
}
const basePath = process.env.REACT_APP_BASE_PATH || '';
const LobbyContainer: React.FC<LobbyContainerProps> = ({roomNum, HeadPlayer, nbPlayer, setFirst, started}) => {
const theme=useTheme();
@ -47,7 +49,7 @@ const LobbyContainer: React.FC<LobbyContainerProps> = ({roomNum, HeadPlayer, nbP
if (nbPlayer < 6 && !started) {
socket.off("request lobbies")
setFirst(true)
navigate(dest);
navigate(`${basePath}/${dest}`);
}
else if(started){
handleShowStart()

@ -25,6 +25,9 @@ import { useTheme } from '../Style/ThemeContext';
import { useAuth } from '../Contexts/AuthContext';
import { useNavigate } from 'react-router-dom';
const basePath = process.env.REACT_APP_BASE_PATH || '';
// @ts-ignore
function AppNavbar({changeLocale}) {
const theme = useTheme();
@ -32,12 +35,13 @@ function AppNavbar({changeLocale}) {
const navigate = useNavigate();
function navigateToProfile(){
navigate("/profile")
navigate(`${basePath}/profile`)
}
function navigateToHome(){
navigate("/")
navigate(`${basePath}/`)
}
return (
@ -49,12 +53,15 @@ function AppNavbar({changeLocale}) {
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
<NavDropdown title={<span style={{ color: theme.colors.text }}><FormattedMessage id="play" /></span>} className="navbar-title" id="basic-nav-dropdown">
<NavDropdown.Item href="play"><FormattedMessage id="play_solo" /> </NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item href="play"><FormattedMessage id="create_room" /> </NavDropdown.Item>
<NavDropdown.Item href="play"><FormattedMessage id="join" /> </NavDropdown.Item>
</NavDropdown>
<Nav.Link href="/" style={{ color: theme.colors.text }}>
Jouer
</Nav.Link>
<Nav.Link href="/presentation" style={{ color: theme.colors.text }}>
Présentation
</Nav.Link>
<Nav.Link href="/info" style={{ color: theme.colors.text }}>
Info
</Nav.Link>
</Nav>
<div className='leftdiv'>
<Nav className="ml-auto navbar-title-dd">
@ -100,4 +107,4 @@ function AppNavbar({changeLocale}) {
);
}
export default AppNavbar;
export default AppNavbar;

@ -28,6 +28,8 @@ import User from '../model/User';
const ScoreBoard: React.FC<{ Player: User }> = ({ Player }) => {
const theme=useTheme();
console.log(Player);
return (
// <div className='LeaderBoardiv'>
<div className='LeaderBoardiv'>
@ -37,18 +39,76 @@ const ScoreBoard: React.FC<{ Player: User }> = ({ Player }) => {
className="mb-3">
<Tab eventKey="perso" title="Vos Stats" disabled = { !Player.pseudo.startsWith("Guest_") ? false : true}>
<Container fluid>
<Row>Stats en solo :</Row>
<Row>Stats en MasterMind :</Row>
<Row>
<Col sm={10}>Partie Jouées :</Col>
<Col className='leftRow'>{Player !== null ? Player.soloStats.nbGames : "0"}</Col>
<Col className='leftRow'>{Player !== null ? Player.mastermindStats.nbGames : "0"}</Col>
</Row>
<Row>
<Col sm={10}>Best-Score :</Col>
<Col className='leftRow'>{Player !== null ? Player.soloStats.bestScore : "0"}</Col>
<Col className='leftRow'>{Player !== null ? Player.mastermindStats.bestScore : "0"}</Col>
</Row>
<Row>
<Col sm={10}>Moyenne d'essai :</Col>
<Col className='leftRow'>{Player !== null ? Player.soloStats.avgNbTry : "0"}</Col>
<Col className='leftRow'>{Player !== null ? Player.mastermindStats.avgNbTry : "0"}</Col>
</Row>
<hr/>
<Row>Stats en Enigme facile :</Row>
<Row>
<Col sm={10}>Partie jouée :</Col>
<Col className='leftRow'>{Player !== null ? Player.easyEnigmaStats.nbGames : "0"}</Col>
</Row>
<Row>
<Col sm={10}>Nombre de victoire :</Col>
<Col className='leftRow'>{Player !== null ? Player.easyEnigmaStats.nbWins : "0"}</Col>
</Row>
<Row>
<Col sm={10}>Ratio V/D :</Col>
<Col className='leftRow'>{Player !== null ? Player.easyEnigmaStats.ratio.toFixed(2) + "%" : "00.0%"}</Col>
</Row>
<Row>
<Col sm={10}>Meilleur temps :</Col>
<Col className='leftRow'>{Player !== null ? Player.easyEnigmaStats.bestTime : "0"}</Col>
</Row>
<Row>
<Col sm={10}>Moyenne de temps :</Col>
<Col className='leftRow'>{Player !== null ? Player.easyEnigmaStats.avgTime.toFixed(2) : "0"}</Col>
</Row>
<hr/>
<Row>Stats en Enigme moyenne :</Row>
<Row>
<Col sm={10}>Partie jouée :</Col>
<Col className='leftRow'>{Player !== null ? Player.mediumEnigmaStats.nbGames : "0"}</Col>
</Row>
<Row>
<Col sm={10}>Best-Score :</Col>
<Col className='leftRow'>{Player !== null ? Player.mediumEnigmaStats.bestScore : "0"}</Col>
</Row>
<Row>
<Col sm={10}>Moyenne d'essai :</Col>
<Col className='leftRow'>{Player !== null ? Player.mediumEnigmaStats.avgNbTry.toFixed(2) : "0"}</Col>
</Row>
<hr/>
<Row>Stats en Enigme difficile :</Row>
<Row>
<Col sm={10}>Partie jouée :</Col>
<Col className='leftRow'>{Player !== null ? Player.hardEnigmaStats.nbGames : "0"}</Col>
</Row>
<Row>
<Col sm={10}>Nombre de victoire :</Col>
<Col className='leftRow'>{Player !== null ? Player.hardEnigmaStats.nbWins : "0"}</Col>
</Row>
<Row>
<Col sm={10}>Ratio V/D :</Col>
<Col className='leftRow'>{Player !== null ? Player.hardEnigmaStats.ratio.toFixed(2) + "%" : "00.0%"}</Col>
</Row>
<Row>
<Col sm={10}>Meilleur temps :</Col>
<Col className='leftRow'>{Player !== null ? Player.hardEnigmaStats.bestTime : "0"}</Col>
</Row>
<Row>
<Col sm={10}>Moyenne de temps :</Col>
<Col className='leftRow'>{Player !== null ? Player.hardEnigmaStats.avgTime.toFixed(2) : "0"}</Col>
</Row>
<hr/>
<Row>Stats en ligne :</Row>
@ -61,8 +121,8 @@ const ScoreBoard: React.FC<{ Player: User }> = ({ Player }) => {
<Col className='leftRow'>{Player !== null ? Player.onlineStats.nbWins : "0"}</Col>
</Row>
<Row>
<Col sm={10}>Ratio P/V :</Col>
<Col className='leftRow'>{Player !== null ? Player.onlineStats.ratio : "0"}</Col>
<Col sm={10}>Ratio V/D :</Col>
<Col className='leftRow'>{Player !== null ? Player.onlineStats.ratio.toFixed(2) + "%" : "0"}</Col>
</Row>
</Container>
</Tab>

@ -6,6 +6,7 @@ import './ErrorStyle.css';
import { FormattedMessage } from 'react-intl';
import { Button } from 'react-bootstrap';
const basePath = process.env.REACT_APP_BASE_PATH || '';
//@ts-ignore
@ -28,7 +29,7 @@ function ErrorPage({ code = "", msg = "Something is wrong"}) {
</div>
<div className='centerDivH' style={{margin: "20px"}}>
<Button href='/' variant='danger'>Retour à l'accueil</Button>
<Button href={`${basePath}/join`} variant='danger'>Retour à l'accueil</Button>
</div>
</div>
);

@ -88,7 +88,7 @@ class JSONParser{
static JSONToPlayer(json: any): Player{
switch (json.type){
case "User":
return new User(json.id, json.pseudo, json.profilePicture, json.soloStats, json.onlineStats)
return new User(json.id, json.pseudo, json.profilePicture, json.mastermindStats, json.easyEnigmaStats, json.mediumEnigmaStats ,json.hardEnigmaStatsS, json.onlineStats)
case "EasyBot":
return new EasyBot(json.id, json.pseudo, json.profilePicture)
default:

@ -52,6 +52,8 @@ import Indice from '../model/Indices/Indice';
let cptNavigation = 0
const basePath = process.env.REACT_APP_BASE_PATH || '';
//@ts-ignore
const InGame = ({locale, changeLocale}) => {
@ -66,7 +68,7 @@ const InGame = ({locale, changeLocale}) => {
if (cptNavigation % 2 == 0){
if (navigationType.toString() == "POP"){
socket.emit("player quit")
navigate("/play")
navigate(`${basePath}/play`)
}
}

@ -80,12 +80,13 @@ function Lobbies() {
useEffect(() => {
socket.on("request lobbies", (map) => {
console.log("wesh")
const jsonMap = JSON.parse(map)
const tmpTab: LobbyDataProps[]=[]
for(const item of jsonMap){
tmpTab.push(new LobbyDataProps(item.key, JSONParser.JSONToPlayer(item.value.tab[0]), item.value.tab.length, item.value.started))
}
setLobbyData(tmpTab)
})
}, [])

@ -50,6 +50,8 @@ import { DataSet } from 'vis-network';
let gameStarted = false
let firstLaunch = true
const basePath = process.env.REACT_APP_BASE_PATH || '';
function Lobby() {
const theme=useTheme();
@ -134,7 +136,7 @@ function Lobby() {
gameStarted = true
//socket.off("player left")
//socket.off("new player")
navigate('/game?solo=false&daily=false');
navigate(`${basePath}/game?solo=false&daily=false`);
});
@ -170,7 +172,7 @@ function Lobby() {
setIndicesData(choosenIndices)
first = true
gameStarted = true
navigate('/game?solo=false&daily=false');
navigate(`${basePath}/game?solo=false&daily=false`)
});
socket.on("new player", (tab) =>{
@ -178,23 +180,24 @@ function Lobby() {
for (const p of tab.tab){
tmpTab.push(JSONParser.JSONToPlayer(p))
}
console.log(tmpTab)
setPlayersData(tmpTab)
})
console.log(tmpTab);
setPlayersData(tmpTab);
});
socket.on("room full", () => {
//TODO POP UP pour quand la room est pleine
navigate("/play")
navigate(`${basePath}/play`)
})
socket.on("game started", () => {
//TODO POP UP pour quand la room est pleine
navigate("/play")
navigate(`${basePath}/play`)
})
socket.on("game already started", () => {
//TODO POP UP pour quand la room est pleine
navigate("/play")
navigate(`${basePath}/play`)
})
socket.on("player left", (tab, i) => {

@ -5,6 +5,8 @@ import { useAuth } from '../Contexts/AuthContext';
import AuthService from '../services/AuthService';
import '../Style/Global.css';
const basePath = process.env.REACT_APP_BASE_PATH || '';
const SignIn = () => {
const navigate = useNavigate();
const { login } = useAuth();
@ -18,8 +20,7 @@ const SignIn = () => {
try {
const data = {
pseudo: (event.target as any).pseudo.value,
password: (event.target as any).password.value,
remember: (event.target as any).remember.checked
password: (event.target as any).password.value
};
const validation = await AuthService.validateSignIn(data);
@ -31,13 +32,13 @@ const SignIn = () => {
const result = await AuthService.signIn(data);
// console.log(result);
console.log(result);
setShowConfirmation(true);
setTimeout(async () => {
await login();
navigate('/play'); // 3 secondes avant de rediriger vers la page de connexion
}, 3000);
navigate(`${basePath}/`);
}, 1250);
}
} catch (error: any) {
setError(error.message);
@ -73,19 +74,6 @@ const SignIn = () => {
placeholder="Entrez votre mot de passe ici"
/>
</div>
<div className="mb-3">
<div className="custom-control custom-checkbox">
<input
type="checkbox"
name='remember'
className="custom-control-input"
id="customCheck1"
/>
<label className="custom-control-label" htmlFor="customCheck1">
Se souvenir de moi
</label>
</div>
</div>
<div className="d-grid">
<button type="submit" className="btn btn-primary">
Soumettre <AiOutlineSend/>
@ -104,7 +92,7 @@ const SignIn = () => {
{showConfirmation && (
<div className="alert alert-success" role="alert">
Connexion réussie ! Vous serez redirigé vers votre profil dans 3 secondes.
Connexion réussie ! Vous serez redirigé vers votre profil.
</div>
)}
</div>

@ -34,13 +34,16 @@ import Lobbies from './Lobbies';
let cptNavigation = 0
const basePath = process.env.REACT_APP_BASE_PATH || '';
function NewPlay() {
let first = true
const theme=useTheme()
const {isLoggedIn, login, user, setUserData, manager } = useAuth();
const {setDailyEnigmeData} = useGame()
const {setDailyEnigmeData, setIndicesData, setPersonData, setPersonNetworkData } = useGame()
const target = useRef(null);
@ -52,57 +55,7 @@ function NewPlay() {
}
}
useEffect(() => {
const fetchUserInformation = async () => {
try {
const sessionData = await SessionService.getSession();
// Vérifie si il y a une session
if (sessionData.user) {
// Il y a une session on récupère les infos du joueur
const updatedPlayer: User = new User(socket.id, sessionData.user.pseudo, sessionData.user.profilePicture, {
nbGames: sessionData.user.soloStats.nbGames,
bestScore: sessionData.user.soloStats.bestScore,
avgNbTry: sessionData.user.soloStats.avgNbTry,
},
{
nbGames: sessionData.user.onlineStats.nbGames,
nbWins: sessionData.user.onlineStats.nbWins,
ratio: sessionData.user.onlineStats.ratio,
})
login();
setUserData(updatedPlayer);
} else {
// Pas de session on génère un guest random
const guestPlayer: User = new User(socket.id, 'Guest_' + Math.floor(Math.random() * 1000000), '',
{
nbGames: 0,
bestScore: 0,
avgNbTry: 0,
},
{
nbGames: 0,
nbWins: 0,
ratio: 0,
})
setUserData(guestPlayer);
}
} catch (error) {
console.error(error);
}
};
fetchUserInformation();
}, [isLoggedIn]);
const { setIndicesData, setPersonData, setPersonNetworkData } = useGame();
useEffect(() => {
if (user == null){
manager.userService.fetchUserInformation().then(([user, loggedIn]) =>{
if (user!=null){
@ -147,7 +100,7 @@ function NewPlay() {
setPersonNetworkData(networkPerson)
setIndicesData(choosenIndices)
setIndicesData(choosenIndices)
navigate('/game?solo=true&daily=false');
navigate(`${basePath}/game?solo=true&daily=false`);
}
@ -178,12 +131,12 @@ function NewPlay() {
useEffect(() => {
if (room !== null) {
const nouvelleURL = `/lobby?room=${room}`;
navigate(nouvelleURL);
navigate(`${basePath}${nouvelleURL}`)
}
}, [room, navigate]);
const goBack = () => {
navigate("/lobby?room=" + goBackRoom)
navigate(`${basePath}/lobby?room=${goBackRoom}`)
}
@ -206,7 +159,7 @@ function NewPlay() {
setIndicesData(choosenIndices)
setIndicesData(choosenIndices)
navigate('/game?solo=true&daily=true&easy=true');
navigate(`${basePath}/game?solo=true&daily=true&easy=true`);
setShowOverlay(false);
};
@ -224,7 +177,7 @@ function NewPlay() {
const map = EnigmeDuJourCreator.createEnigme(networkPerson, choosenIndices, choosenPerson, Stub.GenerateIndice())
setDailyEnigmeData(map)
}
navigate('/game?solo=true&daily=true&easy=false');
navigate(`${basePath}/game?solo=true&daily=true&easy=false`);
setShowOverlay(false);
};

@ -20,7 +20,6 @@ import ScoreBoard from '../Components/ScoreBoard';
import defaultImg from "../res/img/Person.png"
/* Types */
import User from '../model/User';
import EnigmeDuJourCreator from '../model/EnigmeDuJourCreator';
import Stub from '../model/Stub';
@ -33,14 +32,15 @@ import Info from '../res/icon/infoGreen.png';
let cptNavigation = 0
const basePath = process.env.REACT_APP_BASE_PATH || '';
function Play() {
let first = true
const theme=useTheme()
const {isLoggedIn, login, user, setUserData, manager } = useAuth();
const {setDailyEnigmeData} = useGame()
const {setDailyEnigmeData, setIndicesData, setPersonData, setPersonNetworkData } = useGame()
const target = useRef(null);
const navigationType = useNavigationType()
@ -54,56 +54,10 @@ function Play() {
useEffect(() => {
const fetchUserInformation = async () => {
try {
const sessionData = await SessionService.getSession();
// Vérifie si il y a une session
if (sessionData.user) {
// Il y a une session on récupère les infos du joueur
const updatedPlayer: User = new User(socket.id, sessionData.user.pseudo, sessionData.user.profilePicture, {
nbGames: sessionData.user.soloStats.nbGames,
bestScore: sessionData.user.soloStats.bestScore,
avgNbTry: sessionData.user.soloStats.avgNbTry,
},
{
nbGames: sessionData.user.onlineStats.nbGames,
nbWins: sessionData.user.onlineStats.nbWins,
ratio: sessionData.user.onlineStats.ratio,
})
login();
setUserData(updatedPlayer);
} else {
// Pas de session on génère un guest random
const guestPlayer: User = new User(socket.id, 'Guest_' + Math.floor(Math.random() * 1000000), '',
{
nbGames: 0,
bestScore: 0,
avgNbTry: 0,
},
{
nbGames: 0,
nbWins: 0,
ratio: 0,
})
setUserData(guestPlayer);
}
} catch (error) {
console.error(error);
}
};
fetchUserInformation();
}, [isLoggedIn]);
const { setIndicesData, setPersonData, setPersonNetworkData } = useGame();
useEffect(() => {
if (user == null){
manager.userService.fetchUserInformation().then(([user, loggedIn]) =>{
console.log(user);
if (user!=null){
if (loggedIn){
login()
@ -146,7 +100,7 @@ function Play() {
setPersonNetworkData(networkPerson)
setIndicesData(choosenIndices)
setIndicesData(choosenIndices)
navigate('/game?solo=true&daily=false');
navigate(`${basePath}/game?solo=true&daily=false`);
}
@ -177,12 +131,12 @@ function Play() {
useEffect(() => {
if (room !== null) {
const nouvelleURL = `/lobby?room=${room}`;
navigate(nouvelleURL);
navigate(`${basePath}${nouvelleURL}`);
}
}, [room, navigate]);
const goBack = () => {
navigate("/lobby?room=" + goBackRoom)
navigate(`${basePath}/lobby?room=${goBackRoom}`)
}
@ -205,7 +159,7 @@ function Play() {
setIndicesData(choosenIndices)
setIndicesData(choosenIndices)
navigate('/game?solo=true&daily=true&easy=true');
navigate(`${basePath}/game?solo=true&daily=true&easy=true`);
setShowOverlay(false);
};
@ -223,7 +177,7 @@ function Play() {
const map = EnigmeDuJourCreator.createEnigme(networkPerson, choosenIndices, choosenPerson, Stub.GenerateIndice())
setDailyEnigmeData(map)
}
navigate('/game?solo=true&daily=true&easy=false');
navigate(`${basePath}/game?solo=true&daily=true&easy=false`);
setShowOverlay(false);
};
@ -286,7 +240,7 @@ function Play() {
<button onClick={createLobby} className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> Créer une partie </button>
<button onClick= {() => navigate("/join")} className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> Rejoindre </button>
<button onClick= {() => navigate(`${basePath}/join`)} className="ButtonNav" style={{backgroundColor: theme.colors.primary, borderColor: theme.colors.secondary}}> Rejoindre </button>
</div>
</div>
<div className='rightContainer'>

@ -1,11 +1,8 @@
import React, { useEffect, useState } from 'react';
import React, { useState } from 'react';
import ProfilePDP from '../Components/ProfilePDP';
import SessionService from '../services/SessionService';
import AuthService from '../services/AuthService';
import { PlayerProps } from '../types/Player';
import { delay, set, update } from 'lodash';
import { socket } from '../SocketConfig';
/* Style */
@ -17,9 +14,6 @@ import Cancel from '../res/icon/cancel.png'
/* Nav */
import { useNavigate } from 'react-router-dom';
/* Model */
import User from '../model/User';
/* Context */
import { useAuth } from '../Contexts/AuthContext';
@ -31,6 +25,8 @@ import Form from 'react-bootstrap/Form';
import ProgressBar from 'react-bootstrap/ProgressBar';
const basePath = process.env.REACT_APP_BASE_PATH || '';
//@ts-ignore
const Profile = () => {
@ -85,22 +81,23 @@ const Profile = () => {
};
//* Vérification de l'ancien mot de passe :
const handleConfirmedAuth = () => {
const handleConfirmedAuth = async () => {
// Vérification de l'ancien mot de passe
// if (oldPassword === user?.password) {
if (oldPassword === 'coucou') { //! pour l'instant c'est 'coucou', mais il faudra mettre le vrai mdp.
console.log('Ancien mot de passe correct.');
setShowWrongPassword(false);
setShowCorrectPassword(true);
setDisableNextStep(false);
setpercent(25);
}
else{
console.log('Ancien mot de passe incorrect.');
setShowWrongPassword(true);
setShowCorrectPassword(false);
setDisableNextStep(true);
if(user){
try {
if (await AuthService.validatePassword(user?.pseudo, oldPassword)) {
console.log('Ancien mot de passe correct.');
setShowWrongPassword(false);
setShowCorrectPassword(true);
setDisableNextStep(false);
setpercent(25);
}
} catch (error) {
console.error(error);
setShowWrongPassword(true);
setShowCorrectPassword(false);
setDisableNextStep(true);
}
}
}
@ -112,24 +109,25 @@ const Profile = () => {
}
//* Modification du mot de passe :
const handlePasswordChange = () => {
const handlePasswordChange = async () => {
//Effectuer la modification du mot de passe
// sinon, affichez une erreur
if (newPassword === confirmNewPassword) {
// SessionService.UpdatePassword(user?.pseudo, newPassword);
// user.password = newPassword;
console.log('Changement de mot de passe');
setpercent(100);
setTimeout(async () => {
setShowPasswordModal(false);
}, 3000);
} else {
//les mots de passe ne correspondent pas
console.error("Les mots de passe ne correspondent pas.");
setShowWrongPassword(true);
setTimeout(async () => {
setShowWrongPassword(false);
}, 1500);
if(user){
if (newPassword === confirmNewPassword) {
await AuthService.updatePassword(user.pseudo, newPassword);
console.log('Changement de mot de passe');
setpercent(100);
setTimeout(async () => {
setShowPasswordModal(false);
}, 1250);
} else {
//les mots de passe ne correspondent pas
console.error("Les mots de passe ne correspondent pas.");
setShowWrongPassword(true);
setTimeout(async () => {
setShowWrongPassword(false);
}, 1250);
}
}
};
@ -180,16 +178,15 @@ const Profile = () => {
if(user!= null){
const pseudo = user.pseudo;
AuthService.delAccount(pseudo);
AuthService.logout();
logout();
AuthService.delAccount(pseudo);
}
else{
console.error("l'utilisateur ne peut pas être null")
}
handleCloseDeleteModal();
navigate("/play")
navigate(`${basePath}/`)
} else {
console.error('Phrase de confirmation incorrecte.');

@ -4,6 +4,9 @@ import { useNavigate } from 'react-router-dom';
import AuthService from '../services/AuthService';
import '../Style/Global.css';
const basePath = process.env.REACT_APP_BASE_PATH || '';
const SignUp = () => {
const navigate = useNavigate();
@ -32,8 +35,8 @@ const SignUp = () => {
setShowConfirmation(true);
setTimeout(() => {
navigate('/login'); // 3 secondes avant de rediriger vers la page de connexion
}, 3000);
navigate(`${basePath}/login`); // 3 secondes avant de rediriger vers la page de connexion
}, 1250);
}
} catch (error: any) {
setError(error.message);
@ -101,7 +104,7 @@ const SignUp = () => {
{showConfirmation && (
<div className="alert alert-success" role="alert">
Inscription réussie ! Vous serez redirigé vers la page de connexion dans 3 secondes.
Inscription réussie ! Vous serez redirigé vers la page de connexion.
</div>
)}
</div>

@ -1,3 +1,4 @@
import { random } from "lodash";
import SessionService from "../../services/SessionService";
import { socket } from "../../SocketConfig";
import User from "../User";
@ -10,33 +11,72 @@ class DbUserService implements IUserService{
// Vérifie si il y a une session
if (sessionData.user) {
// Il y a une session on récupère les infos du joueur
const updatedPlayer: User = new User(socket.id, sessionData.user.pseudo, sessionData.user.profilePicture, {
nbGames: sessionData.user.soloStats.nbGames,
bestScore: sessionData.user.soloStats.bestScore,
avgNbTry: sessionData.user.soloStats.avgNbTry,
const currentUser = new User(socket.id, sessionData.user.pseudo, sessionData.profilePicture,
{
nbGames: sessionData.user.mastermindStats.nbGames,
bestScore: sessionData.user.mastermindStats.bestScore,
avgNbTry: sessionData.user.mastermindStats.avgNbTry
},
{
nbGames: sessionData.user.easyEnigmaStats.nbGames,
nbWins: sessionData.user.easyEnigmaStats.nbWins,
ratio: sessionData.user.easyEnigmaStats.ratio,
bestTime: sessionData.user.easyEnigmaStats.bestTime,
avgTime: sessionData.user.easyEnigmaStats.avgTime
},
{
nbGames: sessionData.user.mediumEnigmaStats.nbGames,
bestScore: sessionData.user.mediumEnigmaStats.bestScore,
avgNbTry: sessionData.user.mediumEnigmaStats.avgNbTry
},
{
nbGames: sessionData.user.hardEnigmaStats.nbGames,
nbWins: sessionData.user.hardEnigmaStats.nbWins,
ratio: sessionData.user.hardEnigmaStats.ratio,
bestTime: sessionData.user.hardEnigmaStats.bestTime,
avgTime: sessionData.user.hardEnigmaStats.avgTime
},
{
nbGames: sessionData.user.onlineStats.nbGames,
nbWins: sessionData.user.onlineStats.nbWins,
ratio: sessionData.user.onlineStats.ratio,
})
return [updatedPlayer, true]
} else {
// Pas de session on génère un guest random
const guestPlayer: User = new User(socket.id, 'Guest_' + Math.floor(Math.random() * 1000000), '',
});
return [currentUser, true];
}
else{
const guestUser = new User(socket.id, "Guest_" + random(1000, 9999), "",
{
nbGames: 0,
bestScore: 0,
avgNbTry: 0
},
{
nbGames: 0,
nbWins: 0,
ratio: 0,
bestTime: 0,
avgTime: 0
},
{
nbGames: 0,
bestScore: 0,
avgNbTry: 0,
avgNbTry: 0
},
{
nbGames: 0,
nbWins: 0,
ratio: 0,
bestTime: 0,
avgTime: 0
},
{
nbGames: 0,
nbWins: 0,
ratio: 0,
})
return [guestPlayer, false]
});
return [guestUser, false];
}
} catch (error) {
console.error(error);
@ -44,9 +84,9 @@ class DbUserService implements IUserService{
}
}
async updateSoloStats(pseudo: string, nbGames: number, bestScore: number, avgNbTry: number): Promise<void> {
async addMastermindStats(pseudo: string, score: number, time: number): Promise<void> {
try {
const result = await SessionService.updateSoloStats(pseudo, nbGames, bestScore, avgNbTry);
const result = await SessionService.addMastermindStats(pseudo, score, time);
if (result) {
console.log("Stats solo updated");
} else {
@ -57,9 +97,48 @@ class DbUserService implements IUserService{
}
}
async updateOnlineStats(pseudo: string, nbGames: number, bestScore: number, ratio: number): Promise<void> {
async addEasyEnigmaStats(pseudo: string, win: number, time: number): Promise<void> {
try {
const result = await SessionService.addEasyEnigmaStats(pseudo, win, time);
if (result) {
console.log("Stats easy updated");
} else {
console.log("Stats easy not updated");
}
} catch (error) {
console.error(error);
}
}
// async addMediumEnigmaStats(pseudo: string, win: number, time: number): Promise<void> {
// try {
// const result = await SessionService.addMediumEnigmaStats(pseudo, win, time);
// if (result) {
// console.log("Stats medium updated");
// } else {
// console.log("Stats medium not updated");
// }
// } catch (error) {
// console.error(error);
// }
// }
async addHardEnigmaStats(pseudo: string, win: number, time: number): Promise<void> {
try {
const result = await SessionService.addHardEnigmaStats(pseudo, win, time);
if (result) {
console.log("Stats hard updated");
} else {
console.log("Stats hard not updated");
}
} catch (error) {
console.error(error);
}
}
async addOnlineStats(pseudo: string, win: number, time: number): Promise<void> {
try {
const result = await SessionService.updateOnlineStats(pseudo, nbGames, bestScore, ratio);
const result = await SessionService.addOnlineStats(pseudo, win, time);
if (result) {
console.log("Stats online updated");
} else {

@ -2,8 +2,11 @@ import User from "../User";
interface IUserService{
fetchUserInformation(): Promise<[User | null, boolean]>
updateSoloStats(pseudo: string, nbGames: number, bestScore: number, avgNbTry: number): Promise<void>
updateOnlineStats(pseudo: string, nbGames: number, bestScore: number, ratio: number): Promise<void>
addMastermindStats(pseudo: string, score: number, time: number): Promise<void>
addEasyEnigmaStats(pseudo: string, win: number, time: number): Promise<void>
// addMediumEnigmaStats(pseudo: string, win: number, time: number): Promise<void>
addHardEnigmaStats(pseudo: string, win: number, time: number): Promise<void>
addOnlineStats(pseudo: string, win: number, time: number): Promise<void>
}

@ -2,12 +2,18 @@ import Player from "./Player";
import defaultImg from "../res/img/Person.png"
class User extends Player{
public soloStats: any
public mastermindStats: any
public easyEnigmaStats: any
public mediumEnigmaStats: any
public hardEnigmaStats: any
public onlineStats: any
constructor(id: string, pseudo: string, profilePicture: string, soloStats: any, onlineStats: any){
constructor(id: string, pseudo: string, profilePicture: string, soloStats: any, easyEnigmaStats: any, mediumEnigmaStats: any, hardEnigmaStats: any, onlineStats: any){
super(id, pseudo, profilePicture || defaultImg)
this.soloStats=soloStats
this.mastermindStats=soloStats
this.easyEnigmaStats=easyEnigmaStats
this.mediumEnigmaStats=mediumEnigmaStats
this.hardEnigmaStats=hardEnigmaStats
this.onlineStats=onlineStats
}
@ -18,7 +24,9 @@ class User extends Player{
id: this.id,
profilePicture: this.profilePicture,
pseudo: this.pseudo,
soloStats: this.soloStats,
easyEnigmaStats: this.easyEnigmaStats,
mediumEnigmaStats: this.mediumEnigmaStats,
hardEnigmaStats: this.hardEnigmaStats,
onlineStats: this.onlineStats
};
}

@ -1,169 +0,0 @@
const UserService = require('../services/UserService');
const DatabaseService = require('../services/DatabaseService');
const bcrypt = require('bcrypt');
const sqlite3 = require('sqlite3');
class AuthController {
static async signUp(req, res) {
const databaseService = new DatabaseService();
const pseudo = req.body.pseudo;
const date = new Date();
const hour = date.getHours();
const minutes = date.getMinutes();
try {
await databaseService.connect();
// Vérifier que le pseudo n'existe pas déjà
const verif = await databaseService.getUserByPseudo(pseudo);
if (verif) {
res.status(400).json({ error: 'Le pseudo est déjà utilisé.' });
return;
}
// Créer un nouvel utilisateur
const currentUser = await UserService.createUser(req.body);
const insertedUser = await databaseService.insertUser(currentUser);
const user = await databaseService.getUserByPseudo(pseudo);
// Initialiser les stats de l'utilisateur
await databaseService.initSoloStats(user.idUser);
await databaseService.initOnlineStats(user.idUser);
const soloStats = await databaseService.getSoloStatsByUserId(user.idUser);
const onlineStats = await databaseService.getOnlineStatsByUserId(user.idUser);
await databaseService.updateUserIDStats(user.idUser, soloStats.idSoloStats, onlineStats.idOnlineStats);
console.log("[" + hour + ":" + minutes + "] " + user.pseudo + " have been registered.");
res.status(201).json({ message: 'Inscription réussie', user: insertedUser});
}
catch (error) {
// Gérer les erreurs
console.error(error);
res.status(500).json({ error: 'Erreur lors de l\'inscription.' });
}
finally {
await databaseService.disconnect();
}
}
static async signIn(req, res) {
const databaseService = new DatabaseService();
const date = new Date();
const hour = date.getHours();
const minutes = date.getMinutes();
try{
await databaseService.connect();
// Vérifier que le pseudo existe
const pseudo = req.body.pseudo;
const user = await databaseService.getUserByPseudo(pseudo);
if (!user) {
res.status(400).json({ error: 'Le pseudo n\'existe pas.' });
return;
}
// Vérifier que le mot de passe est correct
const password = req.body.password;
const validPassword = await bcrypt.compare(password, user.password);
if (!validPassword) {
res.status(400).json({ error: 'Le mot de passe est incorrect.' });
return;
}
// Stocker l'utilisateur dans la session)
req.session.user = user;
// Envoyer une réponse réussie
console.log("[" + hour + ":" + minutes + "] " + user.pseudo + " have been connected.");
res.status(200).json({ message: 'Connexion réussie', user: user });
}
catch(error){
// Gérer les erreurs
console.error(error);
res.status(500).json({ error: 'Erreur lors de la connexion.' });
}
finally{
await databaseService.disconnect();
}
}
static async logout(req, res) {
const pseudo = req.session.user.pseudo;
const date = new Date();
const hour = date.getHours();
const minutes = date.getMinutes();
// Détruire la session pour déconnecter l'utilisateur
req.session.destroy((err) => {
if (err) {
console.error(err);
res.status(500).json({ error: 'Erreur lors de la déconnexion.' });
} else {
console.log("[" + hour + ":" + minutes + "] " + pseudo + " have been disconnected.");
res.status(200).json({ message: 'Déconnexion réussie' });
}
});
}
static async delAccount(req, res){
const db = new DatabaseService();
try{
await db.connect();
const user = await db.getUserByPseudo(req.body.pseudo);
if(!user){
res.status(400).json({ error: 'Le pseudo n\'existe pas.' });
return;
}
await db.deleteSoloStat(user.idUser);
await db.deleteOnlineStat(user.idUser);
await db.deleteUser(user.idUser);
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la supression du compte.' });
}
finally{
db.disconnect();
}
}
static async UpdateMDP(req, res){
console.log("UpdateMDP");
// const db = new DatabaseService();
// try{
// await db.connect();
// const user = await db.getUserByPseudo(req.body.pseudo);
// console.log("utilisateur" + user.idUser + " pseudo" + user.pseudo)
// if (!user) {
// res.status(200).json({ error: "true", message: 'User not found' });
// return;
// }
// await db.updatePseudo(user.idUser, req.body.newPseudo); //* update
// const updatedUser = await db.getUserByPseudo(req.body.newPseudo);
// console.log("updaetdutilisateur" + updatedUser.idUser + " pseudo" + updatedUser.pseudo)
// req.session.user.pseudo = updatedUser.pseudo;
// console.log("req.session.user.pseudo" + req.session.user.pseudo)
// res.status(200).json({ user: req.session.user }); //verif rep
// }
// catch(error){
// console.error(error);
// res.status(500).json({ error: 'Erreur lors de la modification du pseudo de l\'utilisateur.' });
// }
// finally{
// await db.disconnect();
// }
}
}
module.exports = AuthController;

@ -1,146 +0,0 @@
const DatabaseService = require('../services/DatabaseService');
class SessionController {
static async getUserInformation(req, res) {
const db = new DatabaseService();
const date = new Date();
const hour = date.getHours();
const minutes = date.getMinutes();
try{
await db.connect();
if (!req.session.user) {
res.status(200).json({ error: "true", message: 'User not found' });
return;
}
req.session.user.soloStats = await db.getSoloStatsByUserId(req.session.user.idUser);
req.session.user.onlineStats = await db.getOnlineStatsByUserId(req.session.user.idUser);
console.log("[" + hour + ":" + minutes + "] " + req.session.user.pseudo + " have a session.");
res.status(200).json({ user: req.session.user });
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la récupération de l\'utilisateur.' });
}
finally{
await db.disconnect();
}
}
static async updateSoloStats(req, res) {
const db = new DatabaseService();
const date = new Date();
const hour = date.getHours();
const minutes = date.getMinutes();
try{
await db.connect();
const user = await db.getUserByPseudo(req.body.pseudo);
if (!user) {
res.status(200).json({ error: "true", message: 'User not found' });
return;
}
const soloStats = await db.getSoloStatsByUserId(user.idUser);
if (!soloStats) {
res.status(200).json({ error: "true", message: 'Solo stats not found' });
return;
}
await db.updateSoloStats(user.idUser, req.body.nbGames, req.body.bestScore, req.body.avgNbTry);
const newSoloStats = await db.getSoloStatsByUserId(user.idUser);
req.session.user.soloStats = newSoloStats;
console.log("[" + hour + ":" + minutes + "] " + req.session.user.pseudo + "'s solot_stats are updated.");
res.status(200).json({ user: req.session.user });
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la mise à jour des statistiques solo.' });
}
finally{
await db.disconnect();
}
}
static async updateOnlineStats(req, res) {
const db = new DatabaseService();
const date = new Date();
const hour = date.getHours();
const minutes = date.getMinutes();
try{
await db.connect();
const user = await db.getUserByPseudo(req.body.pseudo);
if (!user) {
res.status(200).json({ error: "true", message: 'User not found' });
return;
}
const onlineStats = await db.getOnlineStatsByUserId(user.idUser);
if (!onlineStats) {
res.status(200).json({ error: "true", message: 'Online stats not found' });
return;
}
await db.updateOnlineStats(user.idUser, req.body.nbGames, req.body.nbWins, req.body.ratio);
const newOnlineStats = await db.getOnlineStatsByUserId(user.idUser);
req.session.user.onlineStats = newOnlineStats;
console.log("[" + hour + ":" + minutes + "] " + req.session.user.pseudo + "'s online_stats are updated.");
res.status(200).json({ user: req.session.user });
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la mise à jour des statistiques en ligne.' });
}
finally{
await db.disconnect();
}
}
static async UpdatePseudo(req, res){
const db = new DatabaseService();
try{
await db.connect();
const user = await db.getUserByPseudo(req.body.pseudo);
console.log("utilisateur" + user.idUser + " pseudo" + user.pseudo)
if (!user) {
res.status(200).json({ error: "true", message: 'User not found' });
return;
}
await db.updatePseudo(user.idUser, req.body.newPseudo); //* update
const updatedUser = await db.getUserByPseudo(req.body.newPseudo);
console.log("updaetdutilisateur" + updatedUser.idUser + " pseudo" + updatedUser.pseudo)
req.session.user.pseudo = updatedUser.pseudo;
console.log("req.session.user.pseudo" + req.session.user.pseudo)
res.status(200).json({ user: req.session.user }); //verif rep
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la modification du pseudo de l\'utilisateur.' });
}
finally{
await db.disconnect();
}
}
}
module.exports = SessionController;

@ -1,231 +0,0 @@
const sqlite3 = require('sqlite3');
const path = require('path');
const { rejects } = require('assert');
class DatabaseService {
constructor(){
this.db_name = "socialgraph";
}
async connect(client){
const dbPath = path.resolve(__dirname, `../db/${this.db_name}.db`)
return new Promise((resolve, reject) => {
this.client = new sqlite3.Database(dbPath,
sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE,
(err) => {
if(err){
reject(err);
}
else{
resolve();
}
});
});
}
async disconnect(){
return new Promise((resolve, reject) => {
this.client.close((err) => {
if(err){
reject(err);
}
else{
resolve();
}
});
});
}
// Récupère l'utilisateur par son pseudo
async getUserByPseudo(pseudo){
return new Promise((resolve, reject) => {
this.client.get('SELECT * FROM users WHERE pseudo = ?', pseudo, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
// Récupère l'utilisateur par son id
async getUserByID(id){
return new Promise((resolve, reject) => {
this.client.get('SELECT * FROM users WHERE idUser = ?', id, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
// Récupère stats solo de l'utilisateur
async getSoloStatsByUserId(userId){
return new Promise((resolve, reject) => {
this.client.get('SELECT * FROM solo_stats WHERE idUser = ?', userId, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
// Récupère stats online de l'utilisateur
async getOnlineStatsByUserId(userId){
return new Promise((resolve, reject) => {
this.client.get('SELECT * FROM online_stats WHERE idUser = ?', userId, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
// insère un utilisateur dans la base de données
async insertUser(user) {
return new Promise((resolve, reject) => {
const { pseudo, password } = user;
this.client.run('INSERT INTO users (pseudo, password) VALUES (?, ?)', [pseudo, password], (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
}
// Mettre à jour l'id de stats solo et online de l'utilisateur
async updateUserIDStats(userId, soloStatsId, onlineStatsId){
return new Promise((resolve, reject) => {
this.client.run('UPDATE users SET idSoloStats = ?, idOnlineStats = ? WHERE idUser = ?', [soloStatsId, onlineStatsId, userId], (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
// Mettre à jour les stats solo de l'utilisateur
async updateSoloStats(userId, nbGames, bestScore, avgNbTry){
return new Promise((resolve, reject) => {
this.client.run('UPDATE solo_stats SET nbGames = ?, bestScore = ?, avgNbTry = ? WHERE idUser = ?', [nbGames, bestScore, avgNbTry, userId], (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
// Mettre à jour les stats online de l'utilisateur
async updateOnlineStats(userId, nbGames, nbWins, ratio){
return new Promise((resolve, reject) => {
this.client.run('UPDATE online_stats SET nbGames = ?, nbWins = ?, ratio = ? WHERE idUser = ?', [nbGames, nbWins, ratio, userId], (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async initSoloStats(userId) {
return new Promise((resolve, reject) => {
this.client.run('INSERT INTO solo_stats (nbGames, bestScore, avgNbTry, idUser) VALUES (?, ?, ?, ?)', 0, 0, 0.0, userId, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async initOnlineStats(userId) {
return new Promise((resolve, reject) => {
this.client.run('INSERT INTO online_stats (nbGames, nbWins, ratio, idUser) VALUES (?, ?, ?, ?)', 0, 0, 0.0, userId, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async deleteUser(userId){
return new Promise((resolve, reject) => {
this.client.run('DELETE FROM users WHERE idUser=?', userId, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async deleteSoloStat(userId){
return new Promise((resolve, reject) => {
this.client.run('DELETE FROM solo_stats WHERE idUser=?', userId, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async deleteOnlineStat(userId){
return new Promise((resolve, reject) => {
this.client.run('DELETE FROM online_stats WHERE idUser=?', userId, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async updatePseudo(userId, newPseudo){
return new Promise((resolve, reject) => {
this.client.run('UPDATE users SET pseudo = ? WHERE idUser = ?', newPseudo, userId, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
}
module.exports = DatabaseService;

@ -1,6 +1,5 @@
import VerificationService from './VerificationService';
import {ADRESSE_DBSERVER} from "../AdressSetup"
import User from '../model/User';
class AuthService{
@ -13,6 +12,30 @@ class AuthService{
return VerificationService.validateSignInData(data);
}
static async validatePassword(pseudo: any, password: any) {
try {
const response = await fetch(ADRESSE_DBSERVER + '/auth/validatePassword', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ pseudo, password }),
credentials: 'include',
});
if (response.ok) {
const result = await response.json();
return result;
} else {
const errorResponse = await response.json();
throw new Error(errorResponse.error);
}
} catch (error) {
console.error(error);
throw error;
}
}
static async signUp(data: any) {
try {
const response = await fetch(ADRESSE_DBSERVER + '/auth/signup', {
@ -110,34 +133,28 @@ class AuthService{
}
static async UpdateMDP(pseudo : string, newmdp : string) {
console.log("pseudo : " + pseudo + " mdp : " + newmdp)
// try {
// const response = await fetch(ADRESSE_DBSERVER + '/session/updateMDP', {
// method: 'PUT',
// headers: {
// 'Content-Type': 'application/json',
// },
// body: JSON.stringify({
// pseudo,
// newmdp
// }),
// credentials: 'include',
// });
// if (response.ok) {
// const result = await response.json();
// return result;
// } else {
// const errorResponse = await response.json();
// throw new Error(errorResponse.error);
// }
// } catch (error) {
// console.error(error);
// throw error;
// }
console.log("UpdateMDP in authserice")
static async updatePassword(pseudo : string, newPassword : string) {
try {
const response = await fetch(ADRESSE_DBSERVER + '/auth/updatePassword', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ pseudo, newPassword }),
credentials: 'include',
});
if (response.ok) {
const result = await response.json();
return result;
} else {
const errorResponse = await response.json();
throw new Error(errorResponse.error);
}
} catch (error) {
console.error(error);
throw error;
}
}
}

@ -24,19 +24,18 @@ class SessionService {
}
}
static async updateSoloStats(pseudo: string, nbGames: number, bestScore: number, avgNbTry: number){
static async addMastermindStats(pseudo: string, score: number, time: number){
try {
const response = await fetch(ADRESSE_DBSERVER + '/session/updateSoloStats', {
method: 'PUT',
const response = await fetch(ADRESSE_DBSERVER + '/session/addMastermindStats', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
body: JSON.stringify({
pseudo,
nbGames,
bestScore,
avgNbTry
score,
time
}),
});
@ -53,21 +52,76 @@ class SessionService {
}
}
static async updateOnlineStats(pseudo: string, nbGames: number, nbWins: number, ratio: number){
static async addEasyEnigmaStats(pseudo: string, win: number, time: number){
try {
const response = await fetch(ADRESSE_DBSERVER + '/session/addEasyEnigmaStats', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
body: JSON.stringify({
pseudo,
win,
time
}),
});
if (response.ok) {
const result = await response.json();
return result;
} else {
const errorResponse = await response.json();
throw new Error(errorResponse.error);
}
} catch (error) {
console.error(error);
throw error;
}
}
console.log("updateOnlineStats : ", pseudo, nbGames, nbWins, ratio);
const response = await fetch(ADRESSE_DBSERVER + '/session/updateOnlineStats', {
method: 'PUT',
// static async addMediumEnigmaStats(pseudo: string, win: number, time: number)
static async addHardEnigmaStats(pseudo: string, win: number, time: number){
try {
const response = await fetch(ADRESSE_DBSERVER + '/session/addHardEnigmaStats', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
body: JSON.stringify({
pseudo,
win,
time
}),
});
if (response.ok) {
const result = await response.json();
return result;
} else {
const errorResponse = await response.json();
throw new Error(errorResponse.error);
}
} catch (error) {
console.error(error);
throw error;
}
}
static async addOnlineStats(pseudo: string, win: number, time: number){
try {
const response = await fetch(ADRESSE_DBSERVER + '/session/addOnlineStats', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
body: JSON.stringify({
pseudo,
nbGames,
nbWins,
ratio
win,
time
}),
});

@ -285,7 +285,7 @@
chalk "^2.4.2"
js-tokens "^4.0.0"
"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.3":
"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.0", "@babel/parser@^7.23.3":
version "7.23.3"
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz"
integrity sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==
@ -1744,7 +1744,7 @@
"@jridgewell/gen-mapping" "^0.3.0"
"@jridgewell/trace-mapping" "^0.3.9"
"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14":
"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15":
version "1.4.15"
resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
@ -2383,6 +2383,11 @@
resolved "https://registry.npmjs.org/@types/mime/-/mime-1.3.4.tgz"
integrity sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw==
"@types/minimatch@^3.0.3":
version "3.0.5"
resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz"
integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==
"@types/node-forge@^1.3.0":
version "1.3.8"
resolved "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.8.tgz"
@ -2683,6 +2688,64 @@
resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz"
integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==
"@vue/compiler-core@3.3.9":
version "3.3.9"
resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.9.tgz"
integrity sha512-+/Lf68Vr/nFBA6ol4xOtJrW+BQWv3QWKfRwGSm70jtXwfhZNF4R/eRgyVJYoxFRhdCTk/F6g99BP0ffPgZihfQ==
dependencies:
"@babel/parser" "^7.23.3"
"@vue/shared" "3.3.9"
estree-walker "^2.0.2"
source-map-js "^1.0.2"
"@vue/compiler-dom@3.3.9":
version "3.3.9"
resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.9.tgz"
integrity sha512-nfWubTtLXuT4iBeDSZ5J3m218MjOy42Vp2pmKVuBKo2/BLcrFUX8nCSr/bKRFiJ32R8qbdnnnBgRn9AdU5v0Sg==
dependencies:
"@vue/compiler-core" "3.3.9"
"@vue/shared" "3.3.9"
"@vue/compiler-sfc@^3.3.4":
version "3.3.9"
resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.9.tgz"
integrity sha512-wy0CNc8z4ihoDzjASCOCsQuzW0A/HP27+0MDSSICMjVIFzk/rFViezkR3dzH+miS2NDEz8ywMdbjO5ylhOLI2A==
dependencies:
"@babel/parser" "^7.23.3"
"@vue/compiler-core" "3.3.9"
"@vue/compiler-dom" "3.3.9"
"@vue/compiler-ssr" "3.3.9"
"@vue/reactivity-transform" "3.3.9"
"@vue/shared" "3.3.9"
estree-walker "^2.0.2"
magic-string "^0.30.5"
postcss "^8.4.31"
source-map-js "^1.0.2"
"@vue/compiler-ssr@3.3.9":
version "3.3.9"
resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.9.tgz"
integrity sha512-NO5oobAw78R0G4SODY5A502MGnDNiDjf6qvhn7zD7TJGc8XDeIEw4fg6JU705jZ/YhuokBKz0A5a/FL/XZU73g==
dependencies:
"@vue/compiler-dom" "3.3.9"
"@vue/shared" "3.3.9"
"@vue/reactivity-transform@3.3.9":
version "3.3.9"
resolved "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.9.tgz"
integrity sha512-HnUFm7Ry6dFa4Lp63DAxTixUp8opMtQr6RxQCpDI1vlh12rkGIeYqMvJtK+IKyEfEOa2I9oCkD1mmsPdaGpdVg==
dependencies:
"@babel/parser" "^7.23.3"
"@vue/compiler-core" "3.3.9"
"@vue/shared" "3.3.9"
estree-walker "^2.0.2"
magic-string "^0.30.5"
"@vue/shared@3.3.9":
version "3.3.9"
resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.3.9.tgz"
integrity sha512-ZE0VTIR0LmYgeyhurPTpy4KzKsuDyQbMSdM49eKkMnT5X4VfFBLysMzjIZhLEFQYjjOVVfbvUDHckwjDFiO2eA==
"@webassemblyjs/ast@^1.11.5", "@webassemblyjs/ast@1.11.6":
version "1.11.6"
resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz"
@ -3083,6 +3146,11 @@ array-buffer-byte-length@^1.0.0:
call-bind "^1.0.2"
is-array-buffer "^3.0.1"
array-differ@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz"
integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==
array-flatten@^2.1.2:
version "2.1.2"
resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz"
@ -3175,6 +3243,11 @@ arraybuffer.prototype.slice@^1.0.2:
is-array-buffer "^3.0.2"
is-shared-array-buffer "^1.0.2"
arrify@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz"
integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==
asap@~2.0.6:
version "2.0.6"
resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz"
@ -3466,11 +3539,6 @@ big.js@^5.2.2:
resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz"
integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
bignumber.js@9.0.0:
version "9.0.0"
resolved "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz"
integrity sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==
binary-extensions@^2.0.0:
version "2.2.0"
resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz"
@ -3639,6 +3707,11 @@ call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5:
get-intrinsic "^1.2.1"
set-function-length "^1.1.1"
callsite@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz"
integrity sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
@ -3662,7 +3735,7 @@ camelcase@^5.3.1:
resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
camelcase@^6.2.0, camelcase@^6.2.1:
camelcase@^6.2.0, camelcase@^6.2.1, camelcase@^6.3.0:
version "6.3.0"
resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz"
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
@ -3988,24 +4061,6 @@ convert-source-map@^2.0.0:
resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz"
integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==
cookie-parser@^1.4.6:
version "1.4.6"
resolved "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz"
integrity sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==
dependencies:
cookie "0.4.1"
cookie-signature "1.0.6"
cookie-session@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/cookie-session/-/cookie-session-2.0.0.tgz"
integrity sha512-hKvgoThbw00zQOleSlUr2qpvuNweoqBtxrmx0UFosx6AGi9lYtLoA+RbsvknrEX8Pr6MDbdWAb2j6SnMn+lPsg==
dependencies:
cookies "0.8.0"
debug "3.2.7"
on-headers "~1.0.2"
safe-buffer "5.2.1"
cookie-signature@1.0.6:
version "1.0.6"
resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz"
@ -4016,11 +4071,6 @@ cookie@~0.4.1:
resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz"
integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
cookie@0.4.1:
version "0.4.1"
resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz"
integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==
cookie@0.4.2:
version "0.4.2"
resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz"
@ -4031,14 +4081,6 @@ cookie@0.5.0:
resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
cookies@0.8.0:
version "0.8.0"
resolved "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz"
integrity sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==
dependencies:
depd "~2.0.0"
keygrip "~1.1.0"
core-js-compat@^3.31.0, core-js-compat@^3.33.1:
version "3.33.2"
resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.2.tgz"
@ -4080,7 +4122,7 @@ cosmiconfig@^6.0.0:
path-type "^4.0.0"
yaml "^1.7.2"
cosmiconfig@^7.0.0:
cosmiconfig@^7.0.0, cosmiconfig@^7.1.0:
version "7.1.0"
resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz"
integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==
@ -4362,13 +4404,6 @@ debug@2.6.9:
dependencies:
ms "2.0.0"
debug@3.2.7:
version "3.2.7"
resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz"
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
dependencies:
ms "^2.1.1"
decimal.js@^10.2.1:
version "10.4.3"
resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz"
@ -4453,6 +4488,35 @@ delegates@^1.0.0:
resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz"
integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
depcheck@^1.4.7:
version "1.4.7"
resolved "https://registry.npmjs.org/depcheck/-/depcheck-1.4.7.tgz"
integrity sha512-1lklS/bV5chOxwNKA/2XUUk/hPORp8zihZsXflr8x0kLwmcZ9Y9BsS6Hs3ssvA+2wUVbG0U2Ciqvm1SokNjPkA==
dependencies:
"@babel/parser" "^7.23.0"
"@babel/traverse" "^7.23.2"
"@vue/compiler-sfc" "^3.3.4"
callsite "^1.0.0"
camelcase "^6.3.0"
cosmiconfig "^7.1.0"
debug "^4.3.4"
deps-regex "^0.2.0"
findup-sync "^5.0.0"
ignore "^5.2.4"
is-core-module "^2.12.0"
js-yaml "^3.14.1"
json5 "^2.2.3"
lodash "^4.17.21"
minimatch "^7.4.6"
multimatch "^5.0.0"
please-upgrade-node "^3.2.0"
readdirp "^3.6.0"
require-package-name "^2.0.1"
resolve "^1.22.3"
resolve-from "^5.0.0"
semver "^7.5.4"
yargs "^16.2.0"
depd@~1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz"
@ -4463,6 +4527,11 @@ depd@~2.0.0, depd@2.0.0:
resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
deps-regex@^0.2.0:
version "0.2.0"
resolved "https://registry.npmjs.org/deps-regex/-/deps-regex-0.2.0.tgz"
integrity sha512-PwuBojGMQAYbWkMXOY9Pd/NWCDNHVH12pnS7WHqZkTSeMESe4hwnKKRp0yR87g37113x4JPbo/oIvXY+s/f56Q==
dequal@^2.0.3:
version "2.0.3"
resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz"
@ -4473,6 +4542,11 @@ destroy@1.2.0:
resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz"
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
detect-file@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz"
integrity sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==
detect-libc@^2.0.0:
version "2.0.2"
resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz"
@ -5211,6 +5285,11 @@ estree-walker@^1.0.1:
resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz"
integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==
estree-walker@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
esutils@^2.0.2:
version "2.0.3"
resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz"
@ -5251,6 +5330,13 @@ exit@^0.1.2:
resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz"
integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==
expand-tilde@^2.0.0, expand-tilde@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz"
integrity sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==
dependencies:
homedir-polyfill "^1.0.1"
expect@^27.5.1:
version "27.5.1"
resolved "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz"
@ -5467,6 +5553,16 @@ find-up@^5.0.0:
locate-path "^6.0.0"
path-exists "^4.0.0"
findup-sync@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz"
integrity sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==
dependencies:
detect-file "^1.0.0"
is-glob "^4.0.3"
micromatch "^4.0.4"
resolve-dir "^1.0.1"
flat-cache@^3.0.4:
version "3.1.1"
resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz"
@ -5724,6 +5820,15 @@ glob@7.1.6:
once "^1.3.0"
path-is-absolute "^1.0.0"
global-modules@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz"
integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==
dependencies:
global-prefix "^1.0.1"
is-windows "^1.0.1"
resolve-dir "^1.0.0"
global-modules@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz"
@ -5731,6 +5836,17 @@ global-modules@^2.0.0:
dependencies:
global-prefix "^3.0.0"
global-prefix@^1.0.1:
version "1.0.2"
resolved "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz"
integrity sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==
dependencies:
expand-tilde "^2.0.2"
homedir-polyfill "^1.0.1"
ini "^1.3.4"
is-windows "^1.0.1"
which "^1.2.14"
global-prefix@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz"
@ -5868,6 +5984,13 @@ hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
dependencies:
react-is "^16.7.0"
homedir-polyfill@^1.0.1:
version "1.0.3"
resolved "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz"
integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==
dependencies:
parse-passwd "^1.0.0"
hoopy@^0.1.4:
version "0.1.4"
resolved "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz"
@ -6058,7 +6181,7 @@ identity-obj-proxy@^3.0.0:
dependencies:
harmony-reflect "^1.4.6"
ignore@^5.2.0:
ignore@^5.2.0, ignore@^5.2.4:
version "5.2.4"
resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz"
integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
@ -6122,7 +6245,7 @@ inherits@2.0.3:
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==
ini@^1.3.5:
ini@^1.3.4, ini@^1.3.5:
version "1.3.8"
resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
@ -6224,7 +6347,7 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7:
resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz"
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
is-core-module@^2.13.0, is-core-module@^2.13.1:
is-core-module@^2.12.0, is-core-module@^2.13.0, is-core-module@^2.13.1:
version "2.13.1"
resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz"
integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==
@ -6412,6 +6535,11 @@ is-weakset@^2.0.1:
call-bind "^1.0.2"
get-intrinsic "^1.1.1"
is-windows@^1.0.1:
version "1.0.2"
resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz"
integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==
is-wsl@^2.2.0:
version "2.2.0"
resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz"
@ -7075,7 +7203,7 @@ jiti@^1.19.1:
resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
js-yaml@^3.13.1:
js-yaml@^3.13.1, js-yaml@^3.14.1:
version "3.14.1"
resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz"
integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
@ -7233,23 +7361,11 @@ jszip@^3.10.1:
readable-stream "~2.3.6"
setimmediate "^1.0.5"
jzip@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/jzip/-/jzip-1.0.0.tgz"
integrity sha512-pyDHf5zvxE5DC47ftNff2AU3UdJe0TYSFki0Ji6GapuZC7p2EizIbPHV7dkLj43RPv2Vj3p1xwC11kDv6dyCrA==
"keycharm@^0.2.0 || ^0.3.0 || ^0.4.0":
version "0.4.0"
resolved "https://registry.npmjs.org/keycharm/-/keycharm-0.4.0.tgz"
integrity sha512-TyQTtsabOVv3MeOpR92sIKk/br9wxS+zGj4BG7CR8YbK4jM3tyIBaF0zhzeBUMx36/Q/iQLOKKOT+3jOQtemRQ==
keygrip@~1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz"
integrity sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==
dependencies:
tsscmp "1.0.6"
keyv@^4.5.3:
version "4.5.4"
resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz"
@ -7441,6 +7557,13 @@ magic-string@^0.25.0, magic-string@^0.25.7:
dependencies:
sourcemap-codec "^1.4.8"
magic-string@^0.30.5:
version "0.30.5"
resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz"
integrity sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==
dependencies:
"@jridgewell/sourcemap-codec" "^1.4.15"
make-dir@^3.0.2, make-dir@^3.1.0:
version "3.1.0"
resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz"
@ -7592,6 +7715,13 @@ minimatch@^5.0.1:
dependencies:
brace-expansion "^2.0.1"
minimatch@^7.4.6:
version "7.4.6"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz"
integrity sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==
dependencies:
brace-expansion "^2.0.1"
minimist@^1.2.0, minimist@^1.2.6:
version "1.2.8"
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz"
@ -7717,15 +7847,16 @@ multicast-dns@^7.2.5:
dns-packet "^5.2.2"
thunky "^1.0.2"
mysql@^2.18.1:
version "2.18.1"
resolved "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz"
integrity sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==
multimatch@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz"
integrity sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==
dependencies:
bignumber.js "9.0.0"
readable-stream "2.3.7"
safe-buffer "5.1.2"
sqlstring "2.3.1"
"@types/minimatch" "^3.0.3"
array-differ "^3.0.0"
array-union "^2.1.0"
arrify "^2.0.1"
minimatch "^3.0.4"
mz@^2.7.0:
version "2.7.0"
@ -8135,6 +8266,11 @@ parse-json@^5.0.0, parse-json@^5.2.0:
json-parse-even-better-errors "^2.3.0"
lines-and-columns "^1.1.6"
parse-passwd@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz"
integrity sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==
parse5@6.0.1:
version "6.0.1"
resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz"
@ -8232,6 +8368,13 @@ pkg-up@^3.1.0:
dependencies:
find-up "^3.0.0"
please-upgrade-node@^3.2.0:
version "3.2.0"
resolved "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz"
integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==
dependencies:
semver-compare "^1.0.0"
postcss-attribute-case-insensitive@^5.0.2:
version "5.0.2"
resolved "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz"
@ -8767,7 +8910,7 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^
resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
"postcss@^7.0.0 || ^8.0.1", postcss@^8, postcss@^8.0.0, postcss@^8.0.3, postcss@^8.0.9, postcss@^8.1.0, postcss@^8.1.4, postcss@^8.2, postcss@^8.2.14, postcss@^8.2.15, postcss@^8.2.2, postcss@^8.3, postcss@^8.3.5, postcss@^8.4, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.4, postcss@^8.4.6, "postcss@>= 8", postcss@>=8, postcss@>=8.0.9:
"postcss@^7.0.0 || ^8.0.1", postcss@^8, postcss@^8.0.0, postcss@^8.0.3, postcss@^8.0.9, postcss@^8.1.0, postcss@^8.1.4, postcss@^8.2, postcss@^8.2.14, postcss@^8.2.15, postcss@^8.2.2, postcss@^8.3, postcss@^8.3.5, postcss@^8.4, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.31, postcss@^8.4.4, postcss@^8.4.6, "postcss@>= 8", postcss@>=8, postcss@>=8.0.9:
version "8.4.31"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz"
integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==
@ -9255,20 +9398,7 @@ readable-stream@~2.3.6:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readable-stream@2.3.7:
version "2.3.7"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~2.0.0"
safe-buffer "~5.1.1"
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readdirp@~3.6.0:
readdirp@^3.6.0, readdirp@~3.6.0:
version "3.6.0"
resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz"
integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
@ -9395,6 +9525,11 @@ require-from-string@^2.0.2:
resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz"
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
require-package-name@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz"
integrity sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==
requires-port@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz"
@ -9407,6 +9542,14 @@ resolve-cwd@^3.0.0:
dependencies:
resolve-from "^5.0.0"
resolve-dir@^1.0.0, resolve-dir@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz"
integrity sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==
dependencies:
expand-tilde "^2.0.0"
global-modules "^1.0.0"
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
@ -9433,7 +9576,7 @@ resolve.exports@^1.1.0:
resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz"
integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==
resolve@^1.1.7, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.2, resolve@^1.22.4:
resolve@^1.1.7, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.2, resolve@^1.22.3, resolve@^1.22.4:
version "1.22.8"
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz"
integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
@ -9517,7 +9660,12 @@ safe-buffer@^5.1.0, safe-buffer@>=5.1.0, safe-buffer@~5.2.0, safe-buffer@5.2.1:
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
safe-buffer@~5.1.0, safe-buffer@~5.1.1, safe-buffer@5.1.2:
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safe-buffer@5.1.2:
version "5.1.2"
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
@ -9618,6 +9766,11 @@ selfsigned@^2.1.1:
"@types/node-forge" "^1.3.0"
node-forge "^1"
semver-compare@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz"
integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==
semver@^6.0.0:
version "6.3.1"
resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
@ -9633,7 +9786,7 @@ semver@^6.3.1:
resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3:
semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4:
version "7.5.4"
resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz"
integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
@ -9953,11 +10106,6 @@ sqlite3@^5.1.6:
optionalDependencies:
node-gyp "8.x"
sqlstring@2.3.1:
version "2.3.1"
resolved "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz"
integrity sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==
ssri@^8.0.0, ssri@^8.0.1:
version "8.0.1"
resolved "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz"
@ -10498,11 +10646,6 @@ tslib@^2.0.3, tslib@^2.4.0:
resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
tsscmp@1.0.6:
version "1.0.6"
resolved "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz"
integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==
tsutils@^3.21.0:
version "3.21.0"
resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz"
@ -11094,6 +11237,13 @@ which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.9:
gopd "^1.0.1"
has-tostringtag "^1.0.0"
which@^1.2.14:
version "1.3.1"
resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz"
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
dependencies:
isexe "^2.0.0"
which@^1.3.1:
version "1.3.1"
resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz"

Loading…
Cancel
Save