diff --git a/.gitignore b/.gitignore index 43a8d1508996bab2a79fd3dd26f21cbc919a37d3..58df814f697435a0a6134847e04a1cb651dd70ec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,9 @@ aws.xml workspace.xml +.gitlab-ci-local +Wiki/.idea + +ExpressAPI/src/config/Version.ts ############################ MacOS # General diff --git a/CHANGELOG.md b/CHANGELOG.md index bf73028d9cc14b5cafaac006e5551f9ebb555b0c..3d352420ac80f93a9101b025cceec9e3014b8fb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,20 @@ **⚠️ Deprecation:** --> -## 2.1.0 (?) +## 2.2.0 (2023-10-16) + +### ✨ Feature +- `results.json` file is now optional (if the teaching staff don't want to provide test details) + - The exercise will be considered as valid if the container exit code is 0 + - The `results.json` file will be construct / completed with the container exit code + - The `volume` argument of `dojo_assignment.json` is now optional (if the teaching staff don't want to provide `results.json` file or other files) +- Client version detection (if the client version is too old, the API will return an error) + +### 🔨 Internal / Developers +- Enhancement in pipelines by splitting them into several files + + +## 2.1.0 (2023-09-29) ### ✨ Feature - Added pipeline badge to exercises diff --git a/ExpressAPI/.env.vault b/ExpressAPI/.env.vault index 0726112735c363e4ce411d6dfc3cd512c39e2d99..7e45ae4669f2d45eb5ff0b09d06bfda38a329afb 100644 --- a/ExpressAPI/.env.vault +++ b/ExpressAPI/.env.vault @@ -4,8 +4,8 @@ #/--------------------------------------------------/ # development -DOTENV_VAULT_DEVELOPMENT="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" +DOTENV_VAULT_DEVELOPMENT="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" # production -DOTENV_VAULT_PRODUCTION="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" +DOTENV_VAULT_PRODUCTION="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" diff --git a/ExpressAPI/assets/assignment_gitlab_ci.yml b/ExpressAPI/assets/assignment_gitlab_ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..ad20a046e037406773064a11f934ebcf69e42f77 --- /dev/null +++ b/ExpressAPI/assets/assignment_gitlab_ci.yml @@ -0,0 +1,26 @@ +################################################################################################################### +# DO NOT MODIFY THIS FILE +# This file is the ci/cd pipeline that will be used to test your assignment +################################################################################################################### + +variables: + GIT_SUBMODULE_STRATEGY: recursive + GIT_SUBMODULE_FORCE_HTTPS: "true" + DOCKER_HOST: tcp://docker:2375 + DOCKER_TLS_CERTDIR: + DOCKER_DRIVER: overlay2 + +stages: + - dojo + +dojo: + stage: dojo + tags: + - dojo_assignment + services: + - docker:dind + image: + name: dojohesso/dojo_assignment_checker:latest + script: + - dojo_assignment_checker + allow_failure: false \ No newline at end of file diff --git a/ExpressAPI/package-lock.json b/ExpressAPI/package-lock.json index 55b1690c568184027ff87bddd32cada603203efe..8f963c7eac7601ac218372bff36cd4a480d1dc0e 100644 --- a/ExpressAPI/package-lock.json +++ b/ExpressAPI/package-lock.json @@ -1,12 +1,13 @@ { "name": "dojo_backend_api", - "version": "2.1.0", + "version": "2.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dojo_backend_api", - "version": "2.1.0", + "version": "2.2.0", + "license": "AGPLv3", "dependencies": { "@prisma/client": "^5.1.1", "ajv": "^8.12.0", @@ -15,6 +16,7 @@ "compression": "^1.7.4", "cors": "^2.8.5", "dotenv": "^16.3.1", + "dotenv-expand": "^10.0.0", "express": "^4.18.2", "express-validator": "^7.0.1", "form-data": "^4.0.0", @@ -28,6 +30,7 @@ "mysql": "^2.18.1", "node": "^20.5.0", "parse-link-header": "^2.0.0", + "semver": "^7.5.4", "tar-stream": "^3.1.6", "uuid": "^9.0.0", "winston": "^3.8.2" @@ -42,9 +45,11 @@ "@types/multer": "^1.4.7", "@types/node": "^20.4.7", "@types/parse-link-header": "^2.0.1", + "@types/semver": "^7.5.3", "@types/tar-stream": "^2.2.2", "@types/uuid": "^9.0.2", "dotenv-vault": "^1.25.0", + "genversion": "^3.1.1", "nodemon": "^3.0.1", "npm": "^9.8.1", "prisma": "^5.1.1", @@ -198,36 +203,12 @@ } } }, - "node_modules/@oclif/core/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@oclif/core/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/@oclif/core/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/@oclif/linewrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@oclif/linewrap/-/linewrap-1.0.0.tgz", @@ -235,9 +216,9 @@ "dev": true }, "node_modules/@oclif/plugin-help": { - "version": "5.2.19", - "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-5.2.19.tgz", - "integrity": "sha512-gf6/dFtzMJ8RA4ovlBCBGJsZsd4jPXhYWJho+Gh6KmA+Ev9LupoExbE0qT+a2uHJyHEvIg4uX/MBW3qdERD/8g==", + "version": "5.2.20", + "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-5.2.20.tgz", + "integrity": "sha512-u+GXX/KAGL9S10LxAwNUaWdzbEBARJ92ogmM7g3gDVud2HioCmvWQCDohNRVZ9GYV9oKwZ/M8xwd6a1d95rEKQ==", "dev": true, "dependencies": { "@oclif/core": "^2.15.0" @@ -302,40 +283,16 @@ } } }, - "node_modules/@oclif/plugin-help/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@oclif/plugin-help/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/@oclif/plugin-help/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/@oclif/plugin-not-found": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@oclif/plugin-not-found/-/plugin-not-found-2.4.1.tgz", - "integrity": "sha512-LqW7qpw5Q8ploRiup2jEIMQJXcxHP1tpwj45GApKQMe7GRdGdRdjBT9Tu+U2tdEgMqgMplAIhOsYCx2nc2nMSw==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@oclif/plugin-not-found/-/plugin-not-found-2.4.3.tgz", + "integrity": "sha512-nIyaR4y692frwh7wIHZ3fb+2L6XEecQwRDIb4zbEam0TvaVmBQWZoColQyWA84ljFBPZ8XWiQyTz+ixSwdRkqg==", "dev": true, "dependencies": { "@oclif/core": "^2.15.0", @@ -402,40 +359,16 @@ } } }, - "node_modules/@oclif/plugin-not-found/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@oclif/plugin-not-found/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/@oclif/plugin-not-found/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/@oclif/plugin-update": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@oclif/plugin-update/-/plugin-update-3.2.3.tgz", - "integrity": "sha512-JVKwp4ysG9GU4RmG59MZYMunz8onRI+wEQzJThyYkUFd0VfZviYt2FHsyoNtxi30l0tInC8APgKp1pCCO4e+FQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@oclif/plugin-update/-/plugin-update-3.2.4.tgz", + "integrity": "sha512-41G7NTKND+yTpb8LHlvlMIcNoaEUIIJuEwju9igL+ME/pN/53opeXgFV2IjjeFiexXj50OfesY9OQ6lqOZHw+g==", "dev": true, "dependencies": { "@oclif/core": "^2.11.8", @@ -511,40 +444,16 @@ } } }, - "node_modules/@oclif/plugin-update/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@oclif/plugin-update/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/@oclif/plugin-update/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/@oclif/plugin-warn-if-update-available": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@oclif/plugin-warn-if-update-available/-/plugin-warn-if-update-available-2.1.0.tgz", - "integrity": "sha512-liTWd/qSIqALsikr88CAB9o2xGFt0LdT5REbhxtrx16/trRmkxQ+0RHK1FieGZAzEENx/4D3YcC/Y67a0uyO0g==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@oclif/plugin-warn-if-update-available/-/plugin-warn-if-update-available-2.1.1.tgz", + "integrity": "sha512-y7eSzT6R5bmTIJbiMMXgOlbBpcWXGlVhNeQJBLBCCy1+90Wbjyqf6uvY0i2WcO4sh/THTJ20qCW80j3XUlgDTA==", "dev": true, "dependencies": { "@oclif/core": "^2.15.0", @@ -614,52 +523,28 @@ } } }, - "node_modules/@oclif/plugin-warn-if-update-available/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@oclif/plugin-warn-if-update-available/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/@oclif/plugin-warn-if-update-available/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/@oclif/screen": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-3.0.6.tgz", - "integrity": "sha512-nEv7dFPxCrWrvK6dQ8zya0/Kb54EXVcwIKV9capjSa89ZDoOo+qH0YSo4/eQVECXgW3eUvgKLDIcIt62YBk0HA==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-3.0.7.tgz", + "integrity": "sha512-jQBPHcMh5rcIPKdqA6xlzioLOmkaVnjg2MVyjMzBKV8hDhLWNSiZqx7NAWXpP70v2LFvGdVoV8BSbK9iID3eHg==", "dev": true, "engines": { "node": ">=12.0.0" } }, "node_modules/@prisma/client": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.1.1.tgz", - "integrity": "sha512-fxcCeK5pMQGcgCqCrWsi+I2rpIbk0rAhdrN+ke7f34tIrgPwA68ensrpin+9+fZvuV2OtzHmuipwduSY6HswdA==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.3.1.tgz", + "integrity": "sha512-ArOKjHwdFZIe1cGU56oIfy7wRuTn0FfZjGuU/AjgEBOQh+4rDkB6nF+AGHP8KaVpkBIiHGPQh3IpwQ3xDMdO0Q==", "hasInstallScript": true, "dependencies": { - "@prisma/engines-version": "5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e" + "@prisma/engines-version": "5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59" }, "engines": { "node": ">=16.13" @@ -674,16 +559,16 @@ } }, "node_modules/@prisma/engines": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.1.1.tgz", - "integrity": "sha512-NV/4nVNWFZSJCCIA3HIFJbbDKO/NARc9ej0tX5S9k2EVbkrFJC4Xt9b0u4rNZWL4V+F5LAjvta8vzEUw0rw+HA==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.3.1.tgz", + "integrity": "sha512-6QkILNyfeeN67BNEPEtkgh3Xo2tm6D7V+UhrkBbRHqKw9CTaz/vvTP/ROwYSP/3JT2MtIutZm/EnhxUiuOPVDA==", "devOptional": true, "hasInstallScript": true }, "node_modules/@prisma/engines-version": { - "version": "5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e.tgz", - "integrity": "sha512-owZqbY/wucbr65bXJ/ljrHPgQU5xXTSkmcE/JcbqE1kusuAXV/TLN3/exmz21SZ5rJ7WDkyk70J2G/n68iogbQ==" + "version": "5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59.tgz", + "integrity": "sha512-y5qbUi3ql2Xg7XraqcXEdMHh0MocBfnBzDn5GbV1xk23S3Mq8MGs+VjacTNiBh3dtEdUERCrUUG7Z3QaJ+h79w==" }, "node_modules/@tsconfig/node10": { "version": "1.0.9", @@ -710,15 +595,15 @@ "dev": true }, "node_modules/@types/bcryptjs": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.2.tgz", - "integrity": "sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.4.tgz", + "integrity": "sha512-9wlJI7k5gRyJEC4yrV7DubzNQFTPiykYxUA6lBtsk5NlOfW9oWLJ1HdIA4YtE+6C3i3mTpDQQEosJ2rVZfBWnw==", "dev": true }, "node_modules/@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.3.tgz", + "integrity": "sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ==", "dev": true, "dependencies": { "@types/connect": "*", @@ -726,45 +611,45 @@ } }, "node_modules/@types/cli-progress": { - "version": "3.11.2", - "resolved": "https://registry.npmjs.org/@types/cli-progress/-/cli-progress-3.11.2.tgz", - "integrity": "sha512-Yt/8rEJalfa9ve2SbfQnwFHrc9QF52JIZYHW3FDaTMpkCvnns26ueKiPHDxyJ0CS//IqjMINTx7R5Xa7k7uFHQ==", + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/@types/cli-progress/-/cli-progress-3.11.3.tgz", + "integrity": "sha512-/+C9xAdVtc+g5yHHkGBThgAA8rYpi5B+2ve3wLtybYj0JHEBs57ivR4x/zGfSsplRnV+psE91Nfin1soNKqz5Q==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/compression": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.7.2.tgz", - "integrity": "sha512-lwEL4M/uAGWngWFLSG87ZDr2kLrbuR8p7X+QZB1OQlT+qkHsCPDVFnHPyXf4Vyl4yDDorNY+mAhosxkCvppatg==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.7.3.tgz", + "integrity": "sha512-rKquEGjebqizyHNMOpaE/4FdYR5VQiWFeesqYfvJU0seSEyB4625UGhNOO/qIkH10S3wftiV7oefc8WdLZ/gCQ==", "dev": true, "dependencies": { "@types/express": "*" } }, "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "version": "3.4.36", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", + "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/cors": { - "version": "2.8.13", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", - "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "version": "2.8.14", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.14.tgz", + "integrity": "sha512-RXHUvNWYICtbP6s18PnOCaqToK8y14DnLd75c6HfyKf228dxy7pHNOQkxPtvXKp/hINFMDjbYzsj63nnpPMSRQ==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/express": { - "version": "4.17.17", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", - "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "version": "4.17.18", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.18.tgz", + "integrity": "sha512-Sxv8BSLLgsBYmcnGdGjjEjqET2U+AKAdCRODmMiq02FgjwuV75Ut85DRpvFjyw/Mk0vgUOliGRU0UUmuuZHByQ==", "dev": true, "dependencies": { "@types/body-parser": "*", @@ -774,9 +659,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.35", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", - "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", + "version": "4.17.37", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.37.tgz", + "integrity": "sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg==", "dev": true, "dependencies": { "@types/node": "*", @@ -785,43 +670,49 @@ "@types/send": "*" } }, + "node_modules/@types/http-errors": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.2.tgz", + "integrity": "sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==", + "dev": true + }, "node_modules/@types/jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-drE6uz7QBKq1fYqqoFKTDRdFCPHd5TCub75BM+D+cMx7NU9hUz7SESLfC2fSCXVFMO5Yj8sOWHuGqPgjc+fz0Q==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-b0jGiOgHtZ2jqdPgPnP6WLCXZk1T8p06A/vPGzUvxpFGgKMbjXJDjC5m52ErqBnIuWZFgGoIJyRdeG5AyreJjA==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.3.tgz", + "integrity": "sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg==", "dev": true }, "node_modules/@types/morgan": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.4.tgz", - "integrity": "sha512-cXoc4k+6+YAllH3ZHmx4hf7La1dzUk6keTR4bF4b4Sc0mZxU/zK4wO7l+ZzezXm/jkYj/qC+uYGZrarZdIVvyQ==", + "version": "1.9.6", + "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.6.tgz", + "integrity": "sha512-xfKogz5WcKww2DAiVT9zxMgrqQt+Shq8tDVeLT+otoj6dJnkRkyJxMF51mHtUc3JCPKGk5x1EBU0buuGpfftlQ==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/multer": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.7.tgz", - "integrity": "sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA==", + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.8.tgz", + "integrity": "sha512-VMZOW6mnmMMhA5m3fsCdXBwFwC+a+27/8gctNMuQC4f7UtWcF79KAFGoIfKZ4iqrElgWIa3j5vhMJDp0iikQ1g==", "dev": true, "dependencies": { "@types/express": "*" } }, "node_modules/@types/node": { - "version": "20.4.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.7.tgz", - "integrity": "sha512-bUBrPjEry2QUTsnuEjzjbS7voGWCc30W0qzgMf90GPeDGFRakvrz47ju+oqDAKCXLUCe39u57/ORMl/O/04/9g==", + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz", + "integrity": "sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==", "dev": true }, "node_modules/@types/parse-link-header": { @@ -831,21 +722,27 @@ "dev": true }, "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "version": "6.9.8", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", + "integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==", "dev": true }, "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.5.tgz", + "integrity": "sha512-xrO9OoVPqFuYyR/loIHjnbvvyRZREYKLjxV4+dY6v3FQR3stQ9ZxIGkaclF7YhI9hfjpuTbu14hZEy94qKLtOA==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==", "dev": true }, "node_modules/@types/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", - "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.2.tgz", + "integrity": "sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw==", "dev": true, "dependencies": { "@types/mime": "^1", @@ -853,33 +750,34 @@ } }, "node_modules/@types/serve-static": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", - "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.3.tgz", + "integrity": "sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg==", "dev": true, "dependencies": { + "@types/http-errors": "*", "@types/mime": "*", "@types/node": "*" } }, "node_modules/@types/tar-stream": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@types/tar-stream/-/tar-stream-2.2.2.tgz", - "integrity": "sha512-1AX+Yt3icFuU6kxwmPakaiGrJUwG44MpuiqPg4dSolRFk6jmvs4b3IbUol9wKDLIgU76gevn3EwE8y/DkSJCZQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/tar-stream/-/tar-stream-2.2.3.tgz", + "integrity": "sha512-if3mugZfjVkXOMZdFjIHySxY13r6GXPpyOlsDmLffvyI7tLz9wXE8BFjNivXsvUeyJ1KNlOpfLnag+ISmxgxPw==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/triple-beam": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.2.tgz", - "integrity": "sha512-txGIh+0eDFzKGC25zORnswy+br1Ha7hj5cMVwKIU7+s0U2AxxJru/jZSMU6OC9MJWP6+pc/hc6ZjyZShpsyY2g==" + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.3.tgz", + "integrity": "sha512-6tOUG+nVHn0cJbVp25JFayS5UE6+xlbcNF9Lo9mU7U0zk3zeUShZied4YEQZjy1JBF043FSkdXw8YkUJuVtB5g==" }, "node_modules/@types/uuid": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz", - "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.4.tgz", + "integrity": "sha512-zAuJWQflfx6dYJM62vna+Sn5aeSWhh3OB+wfUEACNcqUSc0AGc5JKl+ycL1vrH7frGTXhJchYjE1Hak8L819dA==", "dev": true }, "node_modules/abbrev": { @@ -901,9 +799,9 @@ } }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -975,24 +873,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/ansi-styles/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/ansi-styles/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/ansicolors": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", @@ -1075,9 +955,9 @@ } }, "node_modules/axios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz", + "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==", "dependencies": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -1126,11 +1006,6 @@ "node": ">= 0.8" } }, - "node_modules/basic-auth/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/bcryptjs": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", @@ -1201,6 +1076,14 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1278,9 +1161,9 @@ } }, "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "engines": { "node": ">= 0.8" } @@ -1326,15 +1209,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chalk/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/chalk/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -1465,17 +1339,21 @@ } }, "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { - "color-name": "1.1.3" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/color-string": { "version": "1.9.1", @@ -1486,6 +1364,19 @@ "simple-swizzle": "^0.2.2" } }, + "node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, "node_modules/colorette": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", @@ -1512,11 +1403,12 @@ } }, "node_modules/commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, "engines": { - "node": "^12.20.0 || >=14" + "node": ">= 10" } }, "node_modules/compressible": { @@ -1547,19 +1439,6 @@ "node": ">= 0.8.0" } }, - "node_modules/compression/node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/compression/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/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1591,6 +1470,25 @@ "node": ">= 0.6" } }, + "node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", @@ -1726,6 +1624,14 @@ "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, + "node_modules/dotenv-expand": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", + "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", + "engines": { + "node": ">=12" + } + }, "node_modules/dotenv-vault": { "version": "1.25.0", "resolved": "https://registry.npmjs.org/dotenv-vault/-/dotenv-vault-1.25.0.tgz", @@ -1823,12 +1729,6 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/error-ex/node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -1936,6 +1836,25 @@ "node": ">= 8.0.0" } }, + "node_modules/express/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", @@ -1956,9 +1875,9 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-fifo": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.0.tgz", - "integrity": "sha512-IgfweLvEpwyA4WgiQe9Nx6VV2QkML2NkvZnk1oKnIzXgXdWxuhF7zw4DvLTPZJn6PIUneiAXPF24QmoEqHTjyw==" + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" }, "node_modules/fast-glob": { "version": "3.3.1", @@ -2100,15 +2019,24 @@ "node": ">= 0.8" } }, + "node_modules/find-package": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-package/-/find-package-1.0.0.tgz", + "integrity": "sha512-yVn71XCCaNgxz58ERTl8nA/8YYtIQDY9mHSrgFBfiFtdNNfY0h183Vh8BRkKxD8x9TUw3ec290uJKhDVxqGZBw==", + "dev": true, + "dependencies": { + "parents": "^1.0.1" + } + }, "node_modules/fn.name": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", "funding": [ { "type": "individual", @@ -2175,9 +2103,9 @@ } }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, @@ -2193,6 +2121,22 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "node_modules/genversion": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/genversion/-/genversion-3.1.1.tgz", + "integrity": "sha512-/H861PMsihhjgX2qqhTN8egM11V04imhA+3JRFY3jjPua2Sy1NqaqqQPjSP8rdM9jZoKpFhVj9g3Fs9XPCjBYQ==", + "dev": true, + "dependencies": { + "commander": "^7.2.0", + "find-package": "^1.0.0" + }, + "bin": { + "genversion": "bin/genversion.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/get-intrinsic": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", @@ -2259,23 +2203,20 @@ "dev": true }, "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", "engines": { "node": ">= 0.4.0" } }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/has-proto": { @@ -2364,9 +2305,9 @@ } }, "node_modules/http-status-codes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.2.0.tgz", - "integrity": "sha512-feERVo9iWxvnejp3SEfm/+oNG517npqL2/PIA8ORjyOZjGC7TwCRQsZylciLS64i6pJ0wRYz3rkXLRwbtFa8Ng==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.3.0.tgz", + "integrity": "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==" }, "node_modules/hyperlinker": { "version": "1.0.0", @@ -2494,9 +2435,10 @@ } }, "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true }, "node_modules/is-binary-path": { "version": "2.1.0", @@ -2511,9 +2453,9 @@ } }, "node_modules/is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", "dependencies": { "has": "^1.0.3" }, @@ -2705,14 +2647,20 @@ } }, "node_modules/jsonwebtoken": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", - "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", "dependencies": { "jws": "^3.2.2", - "lodash": "^4.17.21", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", "ms": "^2.1.1", - "semver": "^7.3.8" + "semver": "^7.5.4" }, "engines": { "node": ">=12", @@ -2744,12 +2692,12 @@ } }, "node_modules/knex": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/knex/-/knex-2.4.2.tgz", - "integrity": "sha512-tMI1M7a+xwHhPxjbl/H9K1kHX+VncEYcvCx5K00M16bWvpYPKAZd6QrCu68PtHAdIZNQPWZn0GVhqVBEthGWCg==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/knex/-/knex-2.5.1.tgz", + "integrity": "sha512-z78DgGKUr4SE/6cm7ku+jHvFT0X97aERh/f0MUKAKgFnwCYBEW4TFBqtHWFYiJFid7fMrtpZ/gxJthvz5mEByA==", "dependencies": { "colorette": "2.0.19", - "commander": "^9.1.0", + "commander": "^10.0.0", "debug": "4.3.4", "escalade": "^3.1.1", "esm": "^3.2.25", @@ -2757,7 +2705,7 @@ "getopts": "2.3.0", "interpret": "^2.2.0", "lodash": "^4.17.21", - "pg-connection-string": "2.5.0", + "pg-connection-string": "2.6.1", "rechoir": "^0.8.0", "resolve-from": "^5.0.0", "tarn": "^3.0.2", @@ -2793,6 +2741,14 @@ } } }, + "node_modules/knex/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "engines": { + "node": ">=14" + } + }, "node_modules/knex/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2830,6 +2786,41 @@ "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", "dev": true }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, "node_modules/lodash.template": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", @@ -3119,11 +3110,6 @@ "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/natural-orderby": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/natural-orderby/-/natural-orderby-2.0.3.tgz", @@ -3142,9 +3128,9 @@ } }, "node_modules/node": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/node/-/node-20.5.0.tgz", - "integrity": "sha512-+mVyKGaCscnINaMNIa+plgDoN9XXb5ksw7FQB78pUmodmftxomwlaU6z6ze1aCbHVB69BGqo84KkyD6NJC9Ifg==", + "version": "20.7.0", + "resolved": "https://registry.npmjs.org/node/-/node-20.7.0.tgz", + "integrity": "sha512-GiKqtgSALW8+W7Zi9T2AI9aME8hJg+1EESH6O7Xmk4k1gJfBKOolpy9gdg8vCyR8dMeJlp5GQZOYnvxsu8v5TA==", "hasInstallScript": true, "dependencies": { "node-bin-setup": "^1.0.0" @@ -3198,12 +3184,33 @@ "ms": "^2.1.1" } }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/nodemon/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/nopt": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", @@ -6452,6 +6459,15 @@ "node": ">=0.10.0" } }, + "node_modules/parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==", + "dev": true, + "dependencies": { + "path-platform": "~0.11.15" + } + }, "node_modules/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -6505,6 +6521,15 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, + "node_modules/path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -6520,9 +6545,9 @@ } }, "node_modules/pg-connection-string": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", - "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.1.tgz", + "integrity": "sha512-w6ZzNu6oMmIzEAYVw+RLK0+nqHPt8K3ZnknKi+g48Ak2pr3dtljJW3o+D/n2zzCG07Zoe9VOX3aiKpj+BN0pjg==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -6537,13 +6562,13 @@ } }, "node_modules/prisma": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.1.1.tgz", - "integrity": "sha512-WJFG/U7sMmcc6TjJTTifTfpI6Wjoh55xl4AzopVwAdyK68L9/ogNo8QQ2cxuUjJf/Wa82z/uhyh3wMzvRIBphg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.3.1.tgz", + "integrity": "sha512-Wp2msQIlMPHe+5k5Od6xnsI/WNG7UJGgFUJgqv/ygc7kOECZapcSz/iU4NIEzISs3H1W9sFLjAPbg/gOqqtB7A==", "devOptional": true, "hasInstallScript": true, "dependencies": { - "@prisma/engines": "5.1.1" + "@prisma/engines": "5.3.1" }, "bin": { "prisma": "build/index.js" @@ -6659,6 +6684,14 @@ "node": ">= 0.8" } }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -6673,11 +6706,6 @@ "util-deprecate": "~1.0.1" } }, - "node_modules/readable-stream/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/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -6719,11 +6747,11 @@ } }, "node_modules/resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "version": "1.22.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", + "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", "dependencies": { - "is-core-module": "^2.11.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -6807,23 +6835,9 @@ } }, "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "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/safe-stable-stringify": { "version": "2.4.3", @@ -6947,6 +6961,11 @@ "is-arrayish": "^0.3.1" } }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/simple-update-notifier": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", @@ -7040,11 +7059,6 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/string_decoder/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/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -7072,15 +7086,18 @@ } }, "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/supports-hyperlinks": { @@ -7096,15 +7113,6 @@ "node": ">=8" } }, - "node_modules/supports-hyperlinks/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/supports-hyperlinks/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7252,9 +7260,12 @@ } }, "node_modules/triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "engines": { + "node": ">= 14.0.0" + } }, "node_modules/ts-node": { "version": "10.9.1", @@ -7347,9 +7358,9 @@ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "node_modules/typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -7404,9 +7415,13 @@ } }, "node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } @@ -7418,9 +7433,9 @@ "dev": true }, "node_modules/validator": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz", - "integrity": "sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==", + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", "engines": { "node": ">= 0.10" } @@ -7470,9 +7485,9 @@ } }, "node_modules/winston": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.8.2.tgz", - "integrity": "sha512-MsE1gRx1m5jdTTO9Ld/vND4krP2To+lgDoMEHGGa4HIlAUyXJtfc7CxQcGXVyz2IBpw5hbFkj2b/AtUdQwyRew==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.10.0.tgz", + "integrity": "sha512-nT6SIDaE9B7ZRO0u3UvdrimG0HkB7dSTAgInQnNR2SOPJ4bvq5q79+pXLftKmP52lJGW15+H5MCK0nM9D3KB/g==", "dependencies": { "@colors/colors": "1.5.0", "@dabh/diagnostics": "^2.0.2", diff --git a/ExpressAPI/package.json b/ExpressAPI/package.json index e3a1c42872dff82d5049813e4d540cd5640c55e3..c251fe54ccd93983fb524e22c7c20c6ff99e0388 100644 --- a/ExpressAPI/package.json +++ b/ExpressAPI/package.json @@ -1,19 +1,21 @@ { "name" : "dojo_backend_api", - "description" : "Backend API for the Dojo Project", - "version" : "2.1.0", - "license" : "", - "author" : "Michaël Minelli <michael-jean.minelli@hesge.ch>", - "main" : "app.js", + "description" : "Backend API of the Dojo project", + "version" : "2.2.0", + "license" : "AGPLv3", + "author" : "Michaël Minelli <dojo@minelli.me>", + "main" : "dist/src/app.js", "scripts" : { "clean" : "rm -R dist/*", - "build" : "npx prisma generate && npx tsc --project ./ && cp -R assets dist/assets", + "dotenv:build" : "npx dotenv-vault local build", + "genversion" : "npx genversion -s -e src/config/Version.ts", + "build" : "npm run genversion; npx prisma generate && npx tsc --project ./ && cp -R assets dist/assets", "database:migrate" : "npx prisma migrate deploy", - "database:seed" : "npx prisma db seed", + "database:seed" : "npm run genversion; npx prisma db seed", "database:deploy" : "npm run database:migrate && npm run database:seed", - "start:dev" : "npx nodemon src/app.ts", - "start:prod" : "NODE_ENV=production npx node --max-http-header-size=1048576 dist/src/app.js", - "start:migrate:prod": "npm run database:deploy && npm run start:prod" + "start:dev" : "npm run genversion; npx nodemon src/app.ts", + "start:prod" : "npm run genversion; NODE_ENV=production npx node --max-http-header-size=1048576 dist/src/app.js", + "start:migrate:prod": "npm run genversion; npm run database:deploy && npm run start:prod" }, "prisma" : { "seed": "node dist/prisma/seed" @@ -26,6 +28,7 @@ "compression" : "^1.7.4", "cors" : "^2.8.5", "dotenv" : "^16.3.1", + "dotenv-expand" : "^10.0.0", "express" : "^4.18.2", "express-validator": "^7.0.1", "form-data" : "^4.0.0", @@ -39,6 +42,7 @@ "mysql" : "^2.18.1", "node" : "^20.5.0", "parse-link-header": "^2.0.0", + "semver" : "^7.5.4", "tar-stream" : "^3.1.6", "uuid" : "^9.0.0", "winston" : "^3.8.2" @@ -53,9 +57,11 @@ "@types/multer" : "^1.4.7", "@types/node" : "^20.4.7", "@types/parse-link-header": "^2.0.1", + "@types/semver" : "^7.5.3", "@types/tar-stream" : "^2.2.2", "@types/uuid" : "^9.0.2", "dotenv-vault" : "^1.25.0", + "genversion" : "^3.1.1", "nodemon" : "^3.0.1", "prisma" : "^5.1.1", "ts-node" : "^10.9.1", diff --git a/ExpressAPI/src/app.ts b/ExpressAPI/src/app.ts index 1250af3da79a7764038ae9c16bc9934e2a4a53ed..bfbc0494636c237af8dae3185fc2670eb0c51b67 100644 --- a/ExpressAPI/src/app.ts +++ b/ExpressAPI/src/app.ts @@ -3,10 +3,12 @@ const path = require('node:path'); if ( process.env.NODE_ENV && process.env.NODE_ENV === 'production' ) { - require('dotenv').config(); + const myEnv = require('dotenv').config(); + require('dotenv-expand').expand(myEnv); } else { require('dotenv').config({ path: path.join(__dirname, '../.env.keys') }); - require('dotenv').config({ DOTENV_KEY: process.env.DOTENV_KEY_DEVELOPMENT }); + const myEnv = require('dotenv').config({ DOTENV_KEY: process.env.DOTENV_KEY_DEVELOPMENT }); + require('dotenv-expand').expand(myEnv); } require('./shared/helpers/TypeScriptExtensions'); // ATTENTION : This line MUST be after the dotenv.config() calls diff --git a/ExpressAPI/src/config/Config.ts b/ExpressAPI/src/config/Config.ts index 4097324791e961ef4c38172662eebc2b166e362d..574f9b2ea0e987c896a5075d4ac6dac7f7dbac55 100644 --- a/ExpressAPI/src/config/Config.ts +++ b/ExpressAPI/src/config/Config.ts @@ -2,6 +2,7 @@ import GitlabVisibility from '../shared/types/Gitlab/GitlabVisibility'; import path from 'path'; import fs from 'fs'; import { Exercise } from '../types/DatabaseTypes'; +import JSON5 from 'json5'; type ConfigGitlabBadge = { link: string, imageUrl: string } @@ -12,23 +13,25 @@ class Config { port: number }; - public jwtConfig: { + public readonly requestClientValidation: { version: { [client: string]: string } }; // { version: { CLIENT: CONDITION } } + + public readonly jwtConfig: { secret: string; expiresIn: number; }; - public permissions: { + public readonly permissions: { teachingStaff: Array<string>; }; - public gitlab: { - apiURL: string; urls: Array<string>; account: { id: number; username: string; token: string; }; group: { root: number; templates: number; assignments: number; exercises: number; }, badges: { pipeline: ConfigGitlabBadge } + public readonly gitlab: { + urls: Array<string>; account: { id: number; username: string; token: string; }; group: { root: number; templates: number; assignments: number; exercises: number; }, badges: { pipeline: ConfigGitlabBadge } }; - public assignment: { + public readonly assignment: { default: { description: string; initReadme: boolean; sharedRunnersEnabled: boolean; visibility: string; wikiEnabled: boolean; template: string }; baseFiles: Array<string>; filename: string }; - public exercise: { + public readonly exercise: { maxSameName: number; resultsFolder: string, pipelineResultsFolder: string; default: { description: string; visibility: string; }; }; @@ -40,36 +43,58 @@ class Config { port: Number(process.env.API_PORT || 30992) }; + this.requestClientValidation = JSON5.parse(process.env.REQUEST_CLIENT_VALIDATION || '{"version": {}}'); + this.jwtConfig = { - secret: process.env.JWT_SECRET_KEY || '', expiresIn: Number(process.env.SESSION_TIMEOUT || 0) + secret : process.env.JWT_SECRET_KEY || '', + expiresIn: Number(process.env.SESSION_TIMEOUT || 0) }; this.permissions = { - teachingStaff: JSON.parse(process.env.ROLES_WITH_TEACHING_STAFF_PERMISSIONS || '[]') + teachingStaff: JSON5.parse(process.env.ROLES_WITH_TEACHING_STAFF_PERMISSIONS || '[]') }; this.gitlab = { - apiURL : process.env.GITLAB_API_URL || '', urls: JSON.parse(process.env.GITLAB_URLS || '[]'), account: { - id: Number(process.env.GITLAB_DOJO_ACCOUNT_ID || 0), username: process.env.GITLAB_DOJO_ACCOUNT_USERNAME || '', token: process.env.GITLAB_DOJO_ACCOUNT_TOKEN || '' - }, group : { - root: Number(process.env.GITLAB_GROUP_ROOT_ID || 0), templates: Number(process.env.GITLAB_GROUP_TEMPLATES_ID || 0), assignments: Number(process.env.GITLAB_GROUP_ASSIGNMENTS_ID || 0), exercises: Number(process.env.GITLAB_GROUP_EXERCISES_ID || 0) - }, badges: { + urls : JSON5.parse(process.env.GITLAB_URLS || '[]'), + account: { + id : Number(process.env.GITLAB_DOJO_ACCOUNT_ID || 0), + username: process.env.GITLAB_DOJO_ACCOUNT_USERNAME || '', + token : process.env.GITLAB_DOJO_ACCOUNT_TOKEN || '' + }, + group : { + root : Number(process.env.GITLAB_GROUP_ROOT_ID || 0), + templates : Number(process.env.GITLAB_GROUP_TEMPLATES_ID || 0), + assignments: Number(process.env.GITLAB_GROUP_ASSIGNMENTS_ID || 0), + exercises : Number(process.env.GITLAB_GROUP_EXERCISES_ID || 0) + }, + badges : { pipeline: { - link: process.env.GITLAB_BADGE_PIPELINE_LINK || '', imageUrl: process.env.GITLAB_BADGE_PIPELINE_IMAGE_URL || '' + link : process.env.GITLAB_BADGE_PIPELINE_LINK || '', + imageUrl: process.env.GITLAB_BADGE_PIPELINE_IMAGE_URL || '' } } }; this.assignment = { - default : { - description: process.env.ASSIGNMENT_DEFAULT_DESCRIPTION?.convertWithEnvVars() ?? '', initReadme: process.env.ASSIGNMENT_DEFAULT_INIT_README?.toBoolean() ?? false, sharedRunnersEnabled: process.env.ASSIGNMENT_DEFAULT_SHARED_RUNNERS_ENABLED?.toBoolean() ?? true, visibility: process.env.ASSIGNMENT_DEFAULT_VISIBILITY || GitlabVisibility.PRIVATE, wikiEnabled: process.env.ASSIGNMENT_DEFAULT_WIKI_ENABLED?.toBoolean() ?? false, template: process.env.ASSIGNMENT_DEFAULT_TEMPLATE?.replace('{{USERNAME}}', this.gitlab.account.username).replace('{{TOKEN}}', this.gitlab.account.token) ?? '' - }, baseFiles: JSON.parse(process.env.ASSIGNMENT_BASE_FILES || '[]'), filename: process.env.ASSIGNMENT_FILENAME || '' + default : { + description : process.env.ASSIGNMENT_DEFAULT_DESCRIPTION?.convertWithEnvVars() ?? '', + initReadme : process.env.ASSIGNMENT_DEFAULT_INIT_README?.toBoolean() ?? false, + sharedRunnersEnabled: process.env.ASSIGNMENT_DEFAULT_SHARED_RUNNERS_ENABLED?.toBoolean() ?? true, + visibility : process.env.ASSIGNMENT_DEFAULT_VISIBILITY || GitlabVisibility.PRIVATE, + wikiEnabled : process.env.ASSIGNMENT_DEFAULT_WIKI_ENABLED?.toBoolean() ?? false, + template : process.env.ASSIGNMENT_DEFAULT_TEMPLATE?.replace('{{USERNAME}}', this.gitlab.account.username).replace('{{TOKEN}}', this.gitlab.account.token) ?? '' + }, + baseFiles: JSON5.parse(process.env.ASSIGNMENT_BASE_FILES || '[]'), + filename : process.env.ASSIGNMENT_FILENAME || '' }; this.exercise = { - maxSameName: Number(process.env.EXERCISE_MAX_SAME_NAME || 0), resultsFolder: process.env.EXERCISE_RESULTS_FOLDER?.convertWithEnvVars() ?? '', pipelineResultsFolder: process.env.EXERCISE_PIPELINE_RESULTS_FOLDER ?? '', //Do not use convertWithEnvVars() because it is used in the exercise creation and muste be interpreted at exercise runtime - default : { - description: process.env.EXERCISE_DEFAULT_DESCRIPTION?.convertWithEnvVars() ?? '', visibility: process.env.EXERCISE_DEFAULT_VISIBILITY || GitlabVisibility.PRIVATE + maxSameName : Number(process.env.EXERCISE_MAX_SAME_NAME || 0), + resultsFolder : process.env.EXERCISE_RESULTS_FOLDER?.convertWithEnvVars() ?? '', + pipelineResultsFolder: process.env.EXERCISE_PIPELINE_RESULTS_FOLDER ?? '', //Do not use convertWithEnvVars() because it is used in the exercise creation and muste be interpreted at exercise runtime + default : { + description: process.env.EXERCISE_DEFAULT_DESCRIPTION?.convertWithEnvVars() ?? '', + visibility : process.env.EXERCISE_DEFAULT_VISIBILITY || GitlabVisibility.PRIVATE } }; diff --git a/ExpressAPI/src/controllers/Session.ts b/ExpressAPI/src/controllers/Session.ts index fd6b85ff39d9e240795a178a1da7bdc2ab84fcc9..77549d8630df98d91b1d4b1e5ef5a7851f91621e 100644 --- a/ExpressAPI/src/controllers/Session.ts +++ b/ExpressAPI/src/controllers/Session.ts @@ -68,9 +68,9 @@ class Session { Send a response to the client Information: Data could be a promise or an object. If it's a promise, we wait on the data to be resolved before sending the response */ - sendResponse(res: express.Response, code: number, data?: any, descriptionOverride?: string) { + sendResponse(res: express.Response, code: number, data?: any, descriptionOverride?: string, internalCode?: number) { Promise.resolve(data).then((toReturn: any) => { - this.getResponse(code, toReturn, descriptionOverride).then(response => { + this.getResponse(internalCode ?? code, toReturn, descriptionOverride).then(response => { res.status(code).json(response); }); }); diff --git a/ExpressAPI/src/express/API.ts b/ExpressAPI/src/express/API.ts index d9040027335181ab03ad25d9cf4bb42cfc5ed49e..55d2fe4765ecb0810e206d456715a1da4895adae 100644 --- a/ExpressAPI/src/express/API.ts +++ b/ExpressAPI/src/express/API.ts @@ -1,18 +1,19 @@ -import { Express } from 'express-serve-static-core'; -import cors from 'cors'; -import morganMiddleware from '../logging/MorganMiddleware'; -import { AddressInfo } from 'net'; -import http from 'http'; -import helmet from 'helmet'; -import express from 'express'; -import WorkerTask from '../process/WorkerTask'; -import multer from 'multer'; -import SessionMiddleware from '../middlewares/SessionMiddleware'; -import Config from '../config/Config'; -import logger from '../shared/logging/WinstonLogger'; -import ParamsCallbackManager from '../middlewares/ParamsCallbackManager'; -import ApiRoutesManager from '../routes/ApiRoutesManager'; -import compression from 'compression'; +import { Express } from 'express-serve-static-core'; +import cors from 'cors'; +import morganMiddleware from '../logging/MorganMiddleware'; +import { AddressInfo } from 'net'; +import http from 'http'; +import helmet from 'helmet'; +import express from 'express'; +import WorkerTask from '../process/WorkerTask'; +import multer from 'multer'; +import SessionMiddleware from '../middlewares/SessionMiddleware'; +import Config from '../config/Config'; +import logger from '../shared/logging/WinstonLogger'; +import ParamsCallbackManager from '../middlewares/ParamsCallbackManager'; +import ApiRoutesManager from '../routes/ApiRoutesManager'; +import compression from 'compression'; +import ClientVersionMiddleware from '../middlewares/ClientVersionMiddleware'; class API implements WorkerTask { @@ -30,6 +31,8 @@ class API implements WorkerTask { this.backend.use(cors()); //Allow CORS requests this.backend.use(compression()); //Compress responses + this.backend.use(ClientVersionMiddleware.register()); + ParamsCallbackManager.register(this.backend); this.backend.use(SessionMiddleware.register()); diff --git a/ExpressAPI/src/managers/GitlabManager.ts b/ExpressAPI/src/managers/GitlabManager.ts index fc80949e8f8a4878cf3d891a3467c907ecd09c2a..fca3977ce07f14eada038511f9106ccf539fba0a 100644 --- a/ExpressAPI/src/managers/GitlabManager.ts +++ b/ExpressAPI/src/managers/GitlabManager.ts @@ -11,11 +11,12 @@ import parseLinkHeader from 'parse-link-header'; import GitlabFile from '../shared/types/Gitlab/GitlabFile'; import express from 'express'; import GitlabRoute from '../shared/types/Gitlab/GitlabRoute'; +import SharedConfig from '../shared/config/SharedConfig'; class GitlabManager { private getApiUrl(route: GitlabRoute): string { - return `${ Config.gitlab.apiURL }${ route }`; + return `${ SharedConfig.gitlab.apiURL }${ route }`; } public async getUserById(id: number): Promise<GitlabUser | undefined> { diff --git a/ExpressAPI/src/managers/HttpManager.ts b/ExpressAPI/src/managers/HttpManager.ts index 80da4d4ec8abf644fa67a3bc6503f462e7625a07..6d04c68f0b0536bfa9bead9a6e78978bf5946c9b 100644 --- a/ExpressAPI/src/managers/HttpManager.ts +++ b/ExpressAPI/src/managers/HttpManager.ts @@ -2,6 +2,7 @@ import axios, { AxiosError, AxiosRequestHeaders } from 'axios'; import Config from '../config/Config'; import FormData from 'form-data'; import logger from '../shared/logging/WinstonLogger'; +import SharedConfig from '../shared/config/SharedConfig'; class HttpManager { @@ -16,7 +17,7 @@ class HttpManager { config.headers = { ...config.headers, ...(config.data as FormData).getHeaders() } as AxiosRequestHeaders; } - if ( config.url && config.url.indexOf(Config.gitlab.apiURL) !== -1 ) { + if ( config.url && config.url.indexOf(SharedConfig.gitlab.apiURL) !== -1 ) { config.headers['PRIVATE-TOKEN'] = Config.gitlab.account.token; } diff --git a/ExpressAPI/src/middlewares/ClientVersionMiddleware.ts b/ExpressAPI/src/middlewares/ClientVersionMiddleware.ts new file mode 100644 index 0000000000000000000000000000000000000000..f4bed40e30357b8fb035c66e3012f582950c817d --- /dev/null +++ b/ExpressAPI/src/middlewares/ClientVersionMiddleware.ts @@ -0,0 +1,35 @@ +import express from 'express'; +import Config from '../config/Config'; +import semver from 'semver/preload'; +import Session from '../controllers/Session'; +import { HttpStatusCode } from 'axios'; +import DojoStatusCode from '../shared/types/Dojo/DojoStatusCode'; + + +class ClientVersionMiddleware { + register(): (req: express.Request, res: express.Response, next: express.NextFunction) => void { + return async (req: express.Request, res: express.Response, next: express.NextFunction) => { + if ( req.headers['client'] && req.headers['client-version'] ) { + const requestClient = req.headers['client'] as string; + const requestClientVersion = req.headers['client-version'] as string; + + for ( const [ client, condition ] of Object.entries(Config.requestClientValidation.version) ) { + if ( requestClient === client ) { + if ( semver.satisfies(semver.valid(semver.coerce(requestClientVersion)) || '0', condition) ) { + next(); + return; + } else { + new Session().sendResponse(res, HttpStatusCode.MethodNotAllowed, {}, `Client version ${ requestClientVersion } is not supported. Please update your client.`, DojoStatusCode.CLIENT_VERSION_NOT_SUPPORTED); + return; + } + } + } + + new Session().sendResponse(res, HttpStatusCode.MethodNotAllowed, {}, `Unsupported client.`, DojoStatusCode.CLIENT_NOT_SUPPORTED); + } + }; + } +} + + +export default new ClientVersionMiddleware(); \ No newline at end of file diff --git a/ExpressAPI/src/routes/AssignmentRoutes.ts b/ExpressAPI/src/routes/AssignmentRoutes.ts index af42e42fe67513b9c926e4c9de601aaed55b2e6a..0e8926263d792b77a20c60ca36b1c64134a5f3d5 100644 --- a/ExpressAPI/src/routes/AssignmentRoutes.ts +++ b/ExpressAPI/src/routes/AssignmentRoutes.ts @@ -20,16 +20,26 @@ import db from '../helpers/DatabaseHelper'; import { Assignment } from '../types/DatabaseTypes'; import AssignmentManager from '../managers/AssignmentManager'; import GitlabVisibility from '../shared/types/Gitlab/GitlabVisibility'; +import fs from 'fs'; +import path from 'path'; +import SharedAssignmentHelper from '../shared/helpers/Dojo/SharedAssignmentHelper'; class AssignmentRoutes implements RoutesManager { private readonly assignmentValidator: ExpressValidator.Schema = { - name : { - trim: true, notEmpty: true - }, members : { - trim: true, notEmpty: true, customSanitizer: DojoValidators.jsonSanitizer - }, template: { - trim: true, custom: DojoValidators.templateUrlValidator, customSanitizer: DojoValidators.templateUrlSanitizer + name : { + trim : true, + notEmpty: true + }, + members : { + trim : true, + notEmpty : true, + customSanitizer: DojoValidators.jsonSanitizer + }, + template: { + trim : true, + custom : DojoValidators.templateUrlValidator, + customSanitizer: DojoValidators.templateUrlSanitizer } }; @@ -78,6 +88,8 @@ class AssignmentRoutes implements RoutesManager { repository = await GitlabManager.createRepository(params.name, Config.assignment.default.description.replace('{{ASSIGNMENT_NAME}}', params.name), Config.assignment.default.visibility, Config.assignment.default.initReadme, Config.gitlab.group.assignments, Config.assignment.default.sharedRunnersEnabled, Config.assignment.default.wikiEnabled, params.template); await GitlabManager.protectBranch(repository.id, '*', true, GitlabAccessLevel.DEVELOPER, GitlabAccessLevel.DEVELOPER, GitlabAccessLevel.OWNER); + + await GitlabManager.addRepositoryBadge(repository.id, Config.gitlab.badges.pipeline.link, Config.gitlab.badges.pipeline.imageUrl, 'Pipeline Status'); } catch ( error ) { if ( error instanceof AxiosError ) { if ( error.response?.data.message.name && error.response.data.message.name == 'has already been taken' ) { @@ -91,6 +103,18 @@ class AssignmentRoutes implements RoutesManager { return res.status(StatusCodes.INTERNAL_SERVER_ERROR).send(); } + try { + await GitlabManager.createFile(repository.id, '.gitlab-ci.yml', fs.readFileSync(path.join(__dirname, '../../assets/assignment_gitlab_ci.yml'), 'base64'), 'Add .gitlab-ci.yml (DO NOT MODIFY THIS FILE)'); + } catch ( error ) { + logger.error(error); + + if ( error instanceof AxiosError ) { + return res.status(error.response?.status ?? HttpStatusCode.InternalServerError).send(); + } + + return res.status(StatusCodes.INTERNAL_SERVER_ERROR).send(); + } + try { await Promise.all(params.members.map(member => member.id).map(async (memberId: number): Promise<GitlabMember | false> => { try { @@ -102,12 +126,20 @@ class AssignmentRoutes implements RoutesManager { const assignment: Assignment = await db.assignment.create({ data: { - name: repository.name, gitlabId: repository.id, gitlabLink: repository.web_url, gitlabCreationInfo: repository as unknown as Prisma.JsonObject, gitlabLastInfo: repository as unknown as Prisma.JsonObject, gitlabLastInfoDate: new Date(), staff: { + name : repository.name, + gitlabId : repository.id, + gitlabLink : repository.web_url, + gitlabCreationInfo: repository as unknown as Prisma.JsonObject, + gitlabLastInfo : repository as unknown as Prisma.JsonObject, + gitlabLastInfoDate: new Date(), + staff : { connectOrCreate: [ ...params.members.map(gitlabUser => { return { - create : { - gitlabId: gitlabUser.id, firstname: gitlabUser.name - }, where: { + create: { + gitlabId : gitlabUser.id, + firstname: gitlabUser.name + }, + where : { gitlabId: gitlabUser.id } }; @@ -129,15 +161,23 @@ class AssignmentRoutes implements RoutesManager { private changeAssignmentPublishedStatus(publish: boolean): (req: express.Request, res: express.Response) => Promise<void> { return async (req: express.Request, res: express.Response): Promise<void> => { + if ( publish ) { + const isPublishable = await SharedAssignmentHelper.isPublishable(req.boundParams.assignment!.gitlabId); + if ( !isPublishable.isPublishable ) { + return req.session.sendResponse(res, StatusCodes.BAD_REQUEST, { lastPipeline: isPublishable.lastPipeline }, isPublishable.status?.message, isPublishable.status?.code); + } + } + try { await GitlabManager.changeRepositoryVisibility(req.boundParams.assignment!.gitlabId, publish ? GitlabVisibility.INTERNAL : GitlabVisibility.PRIVATE); await db.assignment.update({ - where : { + where: { name: req.boundParams.assignment!.name - }, data: { - published: publish - } + }, + data : { + published: publish + } }); req.session.sendResponse(res, StatusCodes.OK); diff --git a/ExpressAPI/src/routes/ExerciseRoutes.ts b/ExpressAPI/src/routes/ExerciseRoutes.ts index 0abd3d1dfcc80cf07e44d447743a431fe3b78b70..e773d8c2f08c1484a830a28edb962e4031d9de73 100644 --- a/ExpressAPI/src/routes/ExerciseRoutes.ts +++ b/ExpressAPI/src/routes/ExerciseRoutes.ts @@ -32,21 +32,36 @@ import ExerciseResultsFile from '../shared/types/Dojo/ExerciseResults class ExerciseRoutes implements RoutesManager { private readonly exerciseValidator: ExpressValidator.Schema = { members: { - trim: true, notEmpty: true, customSanitizer: DojoValidators.jsonSanitizer + trim : true, + notEmpty : true, + customSanitizer: DojoValidators.jsonSanitizer } }; private readonly resultValidator: ExpressValidator.Schema = { - exitCode : { - isInt: true, toInt: true - }, commit : { - trim: true, notEmpty: true, customSanitizer: DojoValidators.jsonSanitizer - }, results : { - trim: true, notEmpty: true, custom: DojoValidators.exerciseResultsValidator, customSanitizer: DojoValidators.jsonSanitizer - }, files : { - trim: true, notEmpty: true, customSanitizer: DojoValidators.jsonSanitizer - }, archiveBase64: { - isBase64: true, notEmpty: true + exitCode : { + isInt: true, + toInt: true + }, + commit : { + trim : true, + notEmpty : true, + customSanitizer: DojoValidators.jsonSanitizer + }, + results : { + trim : true, + notEmpty : true, + custom : DojoValidators.exerciseResultsValidator, + customSanitizer: DojoValidators.jsonSanitizer + }, + files : { + trim : true, + notEmpty : true, + customSanitizer: DojoValidators.jsonSanitizer + }, + archiveBase64: { + isBase64: true, + notEmpty: true } }; @@ -130,12 +145,23 @@ class ExerciseRoutes implements RoutesManager { const exercise: Exercise = await db.exercise.create({ data: { - id: exerciseId, assignmentName: assignment.name, name: repository.name, secret: secret, gitlabId: repository.id, gitlabLink: repository.web_url, gitlabCreationInfo: repository as unknown as Prisma.JsonObject, gitlabLastInfo: repository as unknown as Prisma.JsonObject, gitlabLastInfoDate: new Date(), members: { + id : exerciseId, + assignmentName : assignment.name, + name : repository.name, + secret : secret, + gitlabId : repository.id, + gitlabLink : repository.web_url, + gitlabCreationInfo: repository as unknown as Prisma.JsonObject, + gitlabLastInfo : repository as unknown as Prisma.JsonObject, + gitlabLastInfoDate: new Date(), + members : { connectOrCreate: [ ...params.members.map(gitlabUser => { return { - create : { - gitlabId: gitlabUser.id, firstname: gitlabUser.name - }, where: { + create: { + gitlabId : gitlabUser.id, + firstname: gitlabUser.name + }, + where : { gitlabId: gitlabUser.id } }; @@ -186,7 +212,9 @@ class ExerciseRoutes implements RoutesManager { })); return req.session.sendResponse(res, StatusCodes.OK, { - assignment: (req.boundParams.exercise as Exercise).assignment, assignmentFile: dojoAssignmentFile, immutable: immutableFiles + assignment : (req.boundParams.exercise as Exercise).assignment, + assignmentFile: dojoAssignmentFile, + immutable : immutableFiles }); } @@ -196,7 +224,12 @@ class ExerciseRoutes implements RoutesManager { const result = await db.result.create({ data: { - exerciseId: exercise.id, exitCode: params.exitCode, success: params.results.success, commit: params.commit, results: params.results as unknown as Prisma.JsonObject, files: params.files + exerciseId: exercise.id, + exitCode : params.exitCode, + success : params.results.success!, + commit : params.commit, + results : params.results as unknown as Prisma.JsonObject, + files : params.files } }); diff --git a/ExpressAPI/src/shared b/ExpressAPI/src/shared index 6cff19278f7fa9664793e1d7826d2596597ac080..efe1bf313f57d1826faf935c183d37a0835f8c2d 160000 --- a/ExpressAPI/src/shared +++ b/ExpressAPI/src/shared @@ -1 +1 @@ -Subproject commit 6cff19278f7fa9664793e1d7826d2596597ac080 +Subproject commit efe1bf313f57d1826faf935c183d37a0835f8c2d