From d09f919d4e84002769f64a19315e34d1e0823bf7 Mon Sep 17 00:00:00 2001 From: Astyax NOUREL Date: Wed, 5 Jan 2022 03:47:27 +0100 Subject: [PATCH 1/6] linting the new files + no-fallthrough rule edited update typescript to 4.5.4 update all eslint packages adding nodejs debugger ! better utils/Data file updating to abstract class CloudService --- BackEnd/.eslintrc.js | 5 +- BackEnd/nodemon.json | 2 +- BackEnd/package-lock.json | 2256 +++++++++--------------- BackEnd/package.json | 15 +- BackEnd/src/cloud/CloudService.ts | 95 +- BackEnd/src/cloud/SwiftService.spec.ts | 42 +- BackEnd/src/cloud/SwiftService.ts | 26 +- BackEnd/src/cloud/swift/SwiftError.ts | 22 +- BackEnd/src/controllers/index.ts | 2 +- BackEnd/src/controllers/server.ts | 10 +- BackEnd/src/controllers/upload.ts | 10 +- BackEnd/src/controllers/users.ts | 4 +- BackEnd/src/env/utils.ts | 12 +- BackEnd/src/utils/Data.ts | 75 +- 14 files changed, 990 insertions(+), 1586 deletions(-) diff --git a/BackEnd/.eslintrc.js b/BackEnd/.eslintrc.js index ed98212..588d616 100644 --- a/BackEnd/.eslintrc.js +++ b/BackEnd/.eslintrc.js @@ -21,6 +21,9 @@ module.exports = { FunctionExpression: { parameters: 'off' }, SwitchCase: 1, // level of indentation }], - '@typescript-eslint/type-annotation-spacing': 'error' + 'no-fallthrough': ['error', { 'commentPattern': 'break[\\s\\w]*omitted' }], + '@typescript-eslint/type-annotation-spacing': ['error', { + overrides: { returnType: { before: true } } + }] } } diff --git a/BackEnd/nodemon.json b/BackEnd/nodemon.json index efe78c1..55fecf6 100644 --- a/BackEnd/nodemon.json +++ b/BackEnd/nodemon.json @@ -3,7 +3,7 @@ "start": "clear" }, "execMap": { - "ts": "ts-node -r dotenv/config" + "ts": "node --inspect -r ts-node/register -r dotenv/config" }, "ext": "ts", "ignore": [".git", "node_modules", "dist", "uploads"], diff --git a/BackEnd/package-lock.json b/BackEnd/package-lock.json index 64f912a..b3524fc 100644 --- a/BackEnd/package-lock.json +++ b/BackEnd/package-lock.json @@ -31,6 +31,7 @@ "passport-local": "1.0.0", "rimraf": "^3.0.2", "slug": "4.0.2", + "typescript": "^4.5.4", "unzipper": "^0.10.11" }, "devDependencies": { @@ -40,13 +41,13 @@ "@types/mocha": "^9.0.0", "@types/morgan": "^1.9.3", "@types/node": "^17.0.5", - "@typescript-eslint/eslint-plugin": "^4.28.4", - "@typescript-eslint/parser": "^4.28.4", - "eslint": "^7.31.0", + "@typescript-eslint/eslint-plugin": "^5.9.0", + "@typescript-eslint/parser": "^5.9.0", + "eslint": "^7.12.1", "eslint-config-standard": "^16.0.3", - "eslint-plugin-import": "^2.23.4", + "eslint-plugin-import": "^2.25.4", "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^5.1.0", + "eslint-plugin-promise": "^5.0.0", "mocha": "^9.1.2", "nodemon": "^2.0.13", "ts-node": "^10.2.1" @@ -126,9 +127,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -163,9 +164,9 @@ } }, "node_modules/@humanwhocodes/config-array/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -186,9 +187,9 @@ "dev": true }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, "node_modules/@kubernetes/client-node": { @@ -542,29 +543,31 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.31.2.tgz", - "integrity": "sha512-w63SCQ4bIwWN/+3FxzpnWrDjQRXVEGiTt9tJTRptRXeFvdZc/wLiz3FQUwNQ2CVoRGI6KUWMNUj/pk63noUfcA==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.9.0.tgz", + "integrity": "sha512-qT4lr2jysDQBQOPsCCvpPUZHjbABoTJW8V9ZzIYKHMfppJtpdtzszDYsldwhFxlhvrp7aCHeXD1Lb9M1zhwWwQ==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "4.31.2", - "@typescript-eslint/scope-manager": "4.31.2", - "debug": "^4.3.1", + "@typescript-eslint/experimental-utils": "5.9.0", + "@typescript-eslint/scope-manager": "5.9.0", + "@typescript-eslint/type-utils": "5.9.0", + "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", - "regexpp": "^3.1.0", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", "semver": "^7.3.5", "tsutils": "^3.21.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^4.0.0", - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -589,6 +592,15 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -611,49 +623,49 @@ } }, "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.31.2.tgz", - "integrity": "sha512-3tm2T4nyA970yQ6R3JZV9l0yilE2FedYg8dcXrTar34zC9r6JB7WyBQbpIVongKPlhEMjhQ01qkwrzWy38Bk1Q==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.9.0.tgz", + "integrity": "sha512-ZnLVjBrf26dn7ElyaSKa6uDhqwvAi4jBBmHK1VxuFGPRAxhdi18ubQYSGA7SRiFiES3q9JiBOBHEBStOFkwD2g==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.31.2", - "@typescript-eslint/types": "4.31.2", - "@typescript-eslint/typescript-estree": "4.31.2", + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.9.0", + "@typescript-eslint/types": "5.9.0", + "@typescript-eslint/typescript-estree": "5.9.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "*" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.31.2.tgz", - "integrity": "sha512-EcdO0E7M/sv23S/rLvenHkb58l3XhuSZzKf6DBvLgHqOYdL6YFMYVtreGFWirxaU2mS1GYDby3Lyxco7X5+Vjw==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.9.0.tgz", + "integrity": "sha512-/6pOPz8yAxEt4PLzgbFRDpZmHnXCeZgPDrh/1DaVKOjvn/UPMlWhbx/gA96xRi2JxY1kBl2AmwVbyROUqys5xQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "4.31.2", - "@typescript-eslint/types": "4.31.2", - "@typescript-eslint/typescript-estree": "4.31.2", - "debug": "^4.3.1" + "@typescript-eslint/scope-manager": "5.9.0", + "@typescript-eslint/types": "5.9.0", + "@typescript-eslint/typescript-estree": "5.9.0", + "debug": "^4.3.2" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -662,9 +674,9 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -685,29 +697,78 @@ "dev": true }, "node_modules/@typescript-eslint/scope-manager": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.31.2.tgz", - "integrity": "sha512-2JGwudpFoR/3Czq6mPpE8zBPYdHWFGL6lUNIGolbKQeSNv4EAiHaR5GVDQaLA0FwgcdcMtRk+SBJbFGL7+La5w==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.9.0.tgz", + "integrity": "sha512-DKtdIL49Qxk2a8icF6whRk7uThuVz4A6TCXfjdJSwOsf+9ree7vgQWcx0KOyCdk0i9ETX666p4aMhrRhxhUkyg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.31.2", - "@typescript-eslint/visitor-keys": "4.31.2" + "@typescript-eslint/types": "5.9.0", + "@typescript-eslint/visitor-keys": "5.9.0" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.9.0.tgz", + "integrity": "sha512-uVCb9dJXpBrK1071ri5aEW7ZHdDHAiqEjYznF3HSSvAJXyrkxGOw2Ejibz/q6BXdT8lea8CMI0CzKNFTNI6TEQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "5.9.0", + "debug": "^4.3.2", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/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/@typescript-eslint/types": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.31.2.tgz", - "integrity": "sha512-kWiTTBCTKEdBGrZKwFvOlGNcAsKGJSBc8xLvSjSppFO88AqGxGNYtF36EuEYG6XZ9vT0xX8RNiHbQUKglbSi1w==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.9.0.tgz", + "integrity": "sha512-mWp6/b56Umo1rwyGCk8fPIzb9Migo8YOniBGPAQDNC6C52SeyNGN4gsVwQTAR+RS2L5xyajON4hOLwAGwPtUwg==", "dev": true, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", @@ -715,21 +776,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.2.tgz", - "integrity": "sha512-ieBq8U9at6PvaC7/Z6oe8D3czeW5d//Fo1xkF/s9394VR0bg/UaMYPdARiWyKX+lLEjY3w/FNZJxitMsiWv+wA==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.9.0.tgz", + "integrity": "sha512-kxo3xL2mB7XmiVZcECbaDwYCt3qFXz99tBSuVJR4L/sR7CJ+UNAPrYILILktGj1ppfZ/jNt/cWYbziJUlHl1Pw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.31.2", - "@typescript-eslint/visitor-keys": "4.31.2", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", + "@typescript-eslint/types": "5.9.0", + "@typescript-eslint/visitor-keys": "5.9.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", "semver": "^7.3.5", "tsutils": "^3.21.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", @@ -742,9 +803,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -780,22 +841,31 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.2.tgz", - "integrity": "sha512-PrBId7EQq2Nibns7dd/ch6S6/M4/iwLM9McbgeEbCXfxdwRUNxJ4UNreJ6Gh3fI2GNKNrWnQxKL7oCPmngKBug==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.9.0.tgz", + "integrity": "sha512-6zq0mb7LV0ThExKlecvpfepiB+XEtFv/bzx7/jKSgyXTFD7qjmSu1FoiS0x3OZaiS+UIXpH2vd9O89f02RCtgw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.31.2", - "eslint-visitor-keys": "^2.0.0" + "@typescript-eslint/types": "5.9.0", + "eslint-visitor-keys": "^3.0.0" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", + "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -877,11 +947,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv/node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, "node_modules/ansi-align": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", @@ -912,6 +977,19 @@ "node": ">=4" } }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/append-field": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", @@ -996,16 +1074,16 @@ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, "node_modules/array-includes": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", + "es-abstract": "^1.19.1", "get-intrinsic": "^1.1.1", - "is-string": "^1.0.5" + "is-string": "^1.0.7" }, "engines": { "node": ">= 0.4" @@ -1024,14 +1102,14 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", - "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" + "es-abstract": "^1.19.0" }, "engines": { "node": ">= 0.4" @@ -1175,6 +1253,15 @@ "node": "*" } }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -1275,20 +1362,6 @@ "node": ">=8" } }, - "node_modules/boxen/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/boxen/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -1327,6 +1400,18 @@ "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -1558,6 +1643,33 @@ "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz", "integrity": "sha1-sffn/HPSXn/R1FWtyU4UODAYK1o=" }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -1939,15 +2051,6 @@ "node": ">=8" } }, - "node_modules/dir-glob/node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -2077,19 +2180,10 @@ "node": ">=8.12" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "node_modules/es-abstract": { - "version": "1.18.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.6.tgz", - "integrity": "sha512-kAeIT4cku5eNLNuUKhlmtuk1/TRZvQoYccn6TO0cSVdf1kzB0T7+dYuVK9MWM7l+/53W2Q8M7N2c6MQvhXFcUQ==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", "dev": true, "dependencies": { "call-bind": "^1.0.2", @@ -2103,7 +2197,9 @@ "is-callable": "^1.2.4", "is-negative-zero": "^2.0.1", "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", "is-string": "^1.0.7", + "is-weakref": "^1.0.1", "object-inspect": "^1.11.0", "object-keys": "^1.1.1", "object.assign": "^4.1.2", @@ -2276,13 +2372,13 @@ "dev": true }, "node_modules/eslint-module-utils": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz", - "integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz", + "integrity": "sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==", "dev": true, "dependencies": { "debug": "^3.2.7", - "pkg-dir": "^2.0.0" + "find-up": "^2.1.0" }, "engines": { "node": ">=4" @@ -2347,32 +2443,30 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.24.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz", - "integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==", + "version": "2.25.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", + "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", "dev": true, "dependencies": { - "array-includes": "^3.1.3", - "array.prototype.flat": "^1.2.4", + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.6.2", - "find-up": "^2.0.0", + "eslint-module-utils": "^2.7.2", "has": "^1.0.3", - "is-core-module": "^2.6.0", + "is-core-module": "^2.8.0", + "is-glob": "^4.0.3", "minimatch": "^3.0.4", - "object.values": "^1.1.4", - "pkg-up": "^2.0.0", - "read-pkg-up": "^3.0.0", + "object.values": "^1.1.5", "resolve": "^1.20.0", - "tsconfig-paths": "^3.11.0" + "tsconfig-paths": "^3.12.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, "node_modules/eslint-plugin-import/node_modules/doctrine": { @@ -2387,103 +2481,6 @@ "node": ">=0.10.0" } }, - "node_modules/eslint-plugin-import/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-import/node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-import/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-import/node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-import/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-import/node_modules/read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-import/node_modules/read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "dependencies": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-import/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/eslint-plugin-node": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", @@ -2547,9 +2544,9 @@ } }, "node_modules/eslint-plugin-promise": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.0.tgz", - "integrity": "sha512-NGmI6BH5L12pl7ScQHbg7tvtk4wPxxj8yPHH47NvSmMtFneC077PSeY3huFj06ZWZvtbfxSPt3RuOQD5XcR4ng==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.0.0.tgz", + "integrity": "sha512-6ZoHypc/CbcB3sicGMGro4YmQLbcmoHL5KhDAtE/Gw5p8TrME7fbAlyD6rH+XN/knndMHKpXdk4A4Bq+njzeSQ==", "dev": true, "engines": { "node": "^10.12.0 || >=12.0.0" @@ -2700,12 +2697,6 @@ "node": ">=4" } }, - "node_modules/eslint/node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, "node_modules/eslint/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3071,6 +3062,11 @@ "node >=0.6.0" ] }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, "node_modules/fast-glob": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", @@ -3087,64 +3083,6 @@ "node": ">=8" } }, - "node_modules/fast-glob/node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fast-glob/node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fast-glob/node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/fast-glob/node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/fast-glob/node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -3171,6 +3109,18 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -3188,6 +3138,18 @@ "node": ">= 0.8" } }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -3211,15 +3173,15 @@ } }, "node_modules/flatted": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", - "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", + "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", "dev": true }, "node_modules/follow-redirects": { - "version": "1.14.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", - "integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==", + "version": "1.14.7", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", + "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", "funding": [ { "type": "individual", @@ -3312,6 +3274,20 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/fstream": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", @@ -3398,9 +3374,9 @@ } }, "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3453,9 +3429,9 @@ } }, "node_modules/globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -3488,9 +3464,9 @@ } }, "node_modules/globby/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true, "engines": { "node": ">= 4" @@ -3637,12 +3613,6 @@ "node": ">=10.0.0" } }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, "node_modules/http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", @@ -3727,15 +3697,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/import-lazy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", @@ -3812,12 +3773,6 @@ "node": ">= 0.10" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -3830,6 +3785,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -3871,9 +3838,9 @@ } }, "node_modules/is-core-module": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", - "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", "dependencies": { "has": "^1.0.3" }, @@ -3915,9 +3882,9 @@ } }, "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { "is-extglob": "^2.1.1" @@ -3943,9 +3910,9 @@ } }, "node_modules/is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true, "engines": { "node": ">= 0.4" @@ -3966,6 +3933,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/is-number-object": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", @@ -4015,6 +3991,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -4070,6 +4055,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-yarn-global": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", @@ -4141,12 +4138,6 @@ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, "node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", @@ -4355,21 +4346,6 @@ "node": ">=4" } }, - "node_modules/locate-path/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, "node_modules/lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -4597,6 +4573,19 @@ "node": ">= 0.6" } }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime-db": { "version": "1.45.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", @@ -4675,32 +4664,32 @@ } }, "node_modules/mocha": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.2.tgz", - "integrity": "sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.0.tgz", + "integrity": "sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q==", "dev": true, "dependencies": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.5.2", - "debug": "4.3.2", + "chokidar": "3.5.3", + "debug": "4.3.3", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.1.7", + "glob": "7.2.0", "growl": "1.10.5", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", "minimatch": "3.0.4", "ms": "2.1.3", - "nanoid": "3.1.25", + "nanoid": "3.2.0", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", "which": "2.0.2", - "workerpool": "6.1.5", + "workerpool": "6.2.0", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" @@ -4741,67 +4730,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/mocha/node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/mocha/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/mocha/node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/mocha/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -4832,9 +4766,9 @@ "dev": true }, "node_modules/mocha/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -4866,18 +4800,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha/node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/mocha/node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -4903,26 +4825,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/mocha/node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/mocha/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -4932,27 +4834,6 @@ "node": ">=8" } }, - "node_modules/mocha/node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/mocha/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -5025,18 +4906,6 @@ "node": ">=8" } }, - "node_modules/mocha/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -5052,18 +4921,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/mocha/node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/mocha/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -5273,9 +5130,9 @@ } }, "node_modules/nanoid": { - "version": "3.1.25", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", - "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", + "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", "dev": true, "bin": { "nanoid": "bin/nanoid.cjs" @@ -5332,61 +5189,6 @@ "url": "https://opencollective.com/nodemon" } }, - "node_modules/nodemon/node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/nodemon/node_modules/binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/nodemon/node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nodemon/node_modules/chokidar": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.0.tgz", - "integrity": "sha512-JgQM9JS92ZbFR4P90EvmzNpSGhpPBGBSj10PILeDyYFwp4h2/D9OM03wsJ4zW1fEp4ka2DGrnUeD7FuvQ2aZ2Q==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.1" - } - }, "node_modules/nodemon/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -5396,69 +5198,12 @@ "ms": "^2.1.1" } }, - "node_modules/nodemon/node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nodemon/node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nodemon/node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, "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/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/nodemon/node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/nopt": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", @@ -5474,18 +5219,6 @@ "node": "*" } }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -5546,9 +5279,9 @@ } }, "node_modules/object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5582,14 +5315,14 @@ } }, "node_modules/object.values": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", - "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" + "es-abstract": "^1.19.1" }, "engines": { "node": ">= 0.4" @@ -5976,6 +5709,15 @@ "node": ">= 0.4.0" } }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -6003,6 +5745,15 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/pause": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", @@ -6025,54 +5776,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "dependencies": { - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", - "dev": true, - "dependencies": { - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -6291,6 +5994,18 @@ "minimatch": "^3.0.4" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", @@ -6456,6 +6171,15 @@ "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz", "integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA==" }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/responselike": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", @@ -6661,9 +6385,9 @@ } }, "node_modules/shelljs": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", - "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", "dependencies": { "glob": "^7.0.0", "interpret": "^1.0.0", @@ -6770,46 +6494,14 @@ "integrity": "sha512-c5XbWkwxHU13gAdSvBHQgnGy2sxv/REMz0ugcM0SOSBCO/N4wfU0TDBC3pgdOwVGjZwGnLBTRljXzdVYE+KYNw==" }, "node_modules/sparse-bitfield": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", - "optional": true, - "dependencies": { - "memory-pager": "^1.0.2" - } - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "optional": true, "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "memory-pager": "^1.0.2" } }, - "node_modules/spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", - "dev": true - }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -6891,14 +6583,14 @@ ] }, "node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" @@ -6942,6 +6634,15 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -6975,26 +6676,25 @@ } }, "node_modules/table": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", - "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", + "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", "dev": true, "dependencies": { "ajv": "^8.0.1", - "lodash.clonedeep": "^4.5.0", "lodash.truncate": "^4.4.2", "slice-ansi": "^4.0.0", - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0" + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=10.0.0" } }, "node_modules/table/node_modules/ajv": { - "version": "8.6.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", - "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -7007,12 +6707,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/table/node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, "node_modules/table/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -7128,6 +6822,18 @@ "node": ">=6" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", @@ -7221,9 +6927,9 @@ } }, "node_modules/tsconfig-paths": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", - "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", + "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", @@ -7232,15 +6938,6 @@ "strip-bom": "^3.0.0" } }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -7328,11 +7025,9 @@ } }, "node_modules/typescript": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", - "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", - "dev": true, - "peer": true, + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", + "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -7706,16 +7401,6 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -7810,9 +7495,9 @@ } }, "node_modules/workerpool": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", - "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", "dev": true }, "node_modules/wrappy": { @@ -7975,9 +7660,9 @@ }, "dependencies": { "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { "ms": "2.1.2" @@ -8003,9 +7688,9 @@ }, "dependencies": { "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { "ms": "2.1.2" @@ -8020,9 +7705,9 @@ } }, "@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, "@kubernetes/client-node": { @@ -8357,16 +8042,18 @@ } }, "@typescript-eslint/eslint-plugin": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.31.2.tgz", - "integrity": "sha512-w63SCQ4bIwWN/+3FxzpnWrDjQRXVEGiTt9tJTRptRXeFvdZc/wLiz3FQUwNQ2CVoRGI6KUWMNUj/pk63noUfcA==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.9.0.tgz", + "integrity": "sha512-qT4lr2jysDQBQOPsCCvpPUZHjbABoTJW8V9ZzIYKHMfppJtpdtzszDYsldwhFxlhvrp7aCHeXD1Lb9M1zhwWwQ==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "4.31.2", - "@typescript-eslint/scope-manager": "4.31.2", - "debug": "^4.3.1", + "@typescript-eslint/experimental-utils": "5.9.0", + "@typescript-eslint/scope-manager": "5.9.0", + "@typescript-eslint/type-utils": "5.9.0", + "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", - "regexpp": "^3.1.0", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", "semver": "^7.3.5", "tsutils": "^3.21.0" }, @@ -8380,6 +8067,12 @@ "ms": "2.1.2" } }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -8398,35 +8091,35 @@ } }, "@typescript-eslint/experimental-utils": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.31.2.tgz", - "integrity": "sha512-3tm2T4nyA970yQ6R3JZV9l0yilE2FedYg8dcXrTar34zC9r6JB7WyBQbpIVongKPlhEMjhQ01qkwrzWy38Bk1Q==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.9.0.tgz", + "integrity": "sha512-ZnLVjBrf26dn7ElyaSKa6uDhqwvAi4jBBmHK1VxuFGPRAxhdi18ubQYSGA7SRiFiES3q9JiBOBHEBStOFkwD2g==", "dev": true, "requires": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.31.2", - "@typescript-eslint/types": "4.31.2", - "@typescript-eslint/typescript-estree": "4.31.2", + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.9.0", + "@typescript-eslint/types": "5.9.0", + "@typescript-eslint/typescript-estree": "5.9.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" } }, "@typescript-eslint/parser": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.31.2.tgz", - "integrity": "sha512-EcdO0E7M/sv23S/rLvenHkb58l3XhuSZzKf6DBvLgHqOYdL6YFMYVtreGFWirxaU2mS1GYDby3Lyxco7X5+Vjw==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.9.0.tgz", + "integrity": "sha512-/6pOPz8yAxEt4PLzgbFRDpZmHnXCeZgPDrh/1DaVKOjvn/UPMlWhbx/gA96xRi2JxY1kBl2AmwVbyROUqys5xQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "4.31.2", - "@typescript-eslint/types": "4.31.2", - "@typescript-eslint/typescript-estree": "4.31.2", - "debug": "^4.3.1" + "@typescript-eslint/scope-manager": "5.9.0", + "@typescript-eslint/types": "5.9.0", + "@typescript-eslint/typescript-estree": "5.9.0", + "debug": "^4.3.2" }, "dependencies": { "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { "ms": "2.1.2" @@ -8441,40 +8134,68 @@ } }, "@typescript-eslint/scope-manager": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.31.2.tgz", - "integrity": "sha512-2JGwudpFoR/3Czq6mPpE8zBPYdHWFGL6lUNIGolbKQeSNv4EAiHaR5GVDQaLA0FwgcdcMtRk+SBJbFGL7+La5w==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.9.0.tgz", + "integrity": "sha512-DKtdIL49Qxk2a8icF6whRk7uThuVz4A6TCXfjdJSwOsf+9ree7vgQWcx0KOyCdk0i9ETX666p4aMhrRhxhUkyg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.9.0", + "@typescript-eslint/visitor-keys": "5.9.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.9.0.tgz", + "integrity": "sha512-uVCb9dJXpBrK1071ri5aEW7ZHdDHAiqEjYznF3HSSvAJXyrkxGOw2Ejibz/q6BXdT8lea8CMI0CzKNFTNI6TEQ==", "dev": true, "requires": { - "@typescript-eslint/types": "4.31.2", - "@typescript-eslint/visitor-keys": "4.31.2" + "@typescript-eslint/experimental-utils": "5.9.0", + "debug": "^4.3.2", + "tsutils": "^3.21.0" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, "@typescript-eslint/types": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.31.2.tgz", - "integrity": "sha512-kWiTTBCTKEdBGrZKwFvOlGNcAsKGJSBc8xLvSjSppFO88AqGxGNYtF36EuEYG6XZ9vT0xX8RNiHbQUKglbSi1w==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.9.0.tgz", + "integrity": "sha512-mWp6/b56Umo1rwyGCk8fPIzb9Migo8YOniBGPAQDNC6C52SeyNGN4gsVwQTAR+RS2L5xyajON4hOLwAGwPtUwg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.2.tgz", - "integrity": "sha512-ieBq8U9at6PvaC7/Z6oe8D3czeW5d//Fo1xkF/s9394VR0bg/UaMYPdARiWyKX+lLEjY3w/FNZJxitMsiWv+wA==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.9.0.tgz", + "integrity": "sha512-kxo3xL2mB7XmiVZcECbaDwYCt3qFXz99tBSuVJR4L/sR7CJ+UNAPrYILILktGj1ppfZ/jNt/cWYbziJUlHl1Pw==", "dev": true, "requires": { - "@typescript-eslint/types": "4.31.2", - "@typescript-eslint/visitor-keys": "4.31.2", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", + "@typescript-eslint/types": "5.9.0", + "@typescript-eslint/visitor-keys": "5.9.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", "semver": "^7.3.5", "tsutils": "^3.21.0" }, "dependencies": { "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { "ms": "2.1.2" @@ -8498,13 +8219,21 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.2.tgz", - "integrity": "sha512-PrBId7EQq2Nibns7dd/ch6S6/M4/iwLM9McbgeEbCXfxdwRUNxJ4UNreJ6Gh3fI2GNKNrWnQxKL7oCPmngKBug==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.9.0.tgz", + "integrity": "sha512-6zq0mb7LV0ThExKlecvpfepiB+XEtFv/bzx7/jKSgyXTFD7qjmSu1FoiS0x3OZaiS+UIXpH2vd9O89f02RCtgw==", "dev": true, "requires": { - "@typescript-eslint/types": "4.31.2", - "eslint-visitor-keys": "^2.0.0" + "@typescript-eslint/types": "5.9.0", + "eslint-visitor-keys": "^3.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", + "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "dev": true + } } }, "@ungap/promise-all-settled": { @@ -8565,13 +8294,6 @@ "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" - }, - "dependencies": { - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - } } }, "ansi-align": { @@ -8598,6 +8320,16 @@ "color-convert": "^1.9.0" } }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, "append-field": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", @@ -8678,16 +8410,16 @@ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, "array-includes": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", + "es-abstract": "^1.19.1", "get-intrinsic": "^1.1.1", - "is-string": "^1.0.5" + "is-string": "^1.0.7" } }, "array-union": { @@ -8697,14 +8429,14 @@ "dev": true }, "array.prototype.flat": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", - "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" + "es-abstract": "^1.19.0" } }, "asn1": { @@ -8804,6 +8536,12 @@ "chainsaw": "~0.1.0" } }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -8877,17 +8615,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -8919,6 +8646,15 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -9091,6 +8827,22 @@ "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz", "integrity": "sha1-sffn/HPSXn/R1FWtyU4UODAYK1o=" }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, "chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -9389,14 +9141,6 @@ "dev": true, "requires": { "path-type": "^4.0.0" - }, - "dependencies": { - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - } } }, "doctrine": { @@ -9514,19 +9258,10 @@ "resolved": "https://registry.npmjs.org/envalid/-/envalid-7.1.1.tgz", "integrity": "sha512-2MIPjXAWcAVsO2jTVbgMFRc66lQCy2bQDP+zPT3NucrbWMD3pij5iGZMwQiv3zdveyVfl0qAGpI1JRQGfkmu1w==" }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, "es-abstract": { - "version": "1.18.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.6.tgz", - "integrity": "sha512-kAeIT4cku5eNLNuUKhlmtuk1/TRZvQoYccn6TO0cSVdf1kzB0T7+dYuVK9MWM7l+/53W2Q8M7N2c6MQvhXFcUQ==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -9540,7 +9275,9 @@ "is-callable": "^1.2.4", "is-negative-zero": "^2.0.1", "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", "is-string": "^1.0.7", + "is-weakref": "^1.0.1", "object-inspect": "^1.11.0", "object-keys": "^1.1.1", "object.assign": "^4.1.2", @@ -9697,12 +9434,6 @@ } } }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -9770,13 +9501,13 @@ } }, "eslint-module-utils": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz", - "integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz", + "integrity": "sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==", "dev": true, "requires": { "debug": "^3.2.7", - "pkg-dir": "^2.0.0" + "find-up": "^2.1.0" }, "dependencies": { "debug": { @@ -9824,26 +9555,24 @@ } }, "eslint-plugin-import": { - "version": "2.24.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz", - "integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==", + "version": "2.25.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", + "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", "dev": true, "requires": { - "array-includes": "^3.1.3", - "array.prototype.flat": "^1.2.4", + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.6.2", - "find-up": "^2.0.0", + "eslint-module-utils": "^2.7.2", "has": "^1.0.3", - "is-core-module": "^2.6.0", + "is-core-module": "^2.8.0", + "is-glob": "^4.0.3", "minimatch": "^3.0.4", - "object.values": "^1.1.4", - "pkg-up": "^2.0.0", - "read-pkg-up": "^3.0.0", + "object.values": "^1.1.5", "resolve": "^1.20.0", - "tsconfig-paths": "^3.11.0" + "tsconfig-paths": "^3.12.0" }, "dependencies": { "doctrine": { @@ -9854,79 +9583,6 @@ "requires": { "esutils": "^2.0.2" } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true } } }, @@ -9974,9 +9630,9 @@ } }, "eslint-plugin-promise": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.0.tgz", - "integrity": "sha512-NGmI6BH5L12pl7ScQHbg7tvtk4wPxxj8yPHH47NvSmMtFneC077PSeY3huFj06ZWZvtbfxSPt3RuOQD5XcR4ng==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.0.0.tgz", + "integrity": "sha512-6ZoHypc/CbcB3sicGMGro4YmQLbcmoHL5KhDAtE/Gw5p8TrME7fbAlyD6rH+XN/knndMHKpXdk4A4Bq+njzeSQ==", "dev": true, "requires": {} }, @@ -10247,6 +9903,11 @@ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, "fast-glob": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", @@ -10258,51 +9919,6 @@ "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" - }, - "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } } }, "fast-json-stable-stringify": { @@ -10328,6 +9944,15 @@ "flat-cache": "^3.0.4" } }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -10342,6 +9967,15 @@ "unpipe": "~1.0.0" } }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, "flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -10359,15 +9993,15 @@ } }, "flatted": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", - "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", + "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", "dev": true }, "follow-redirects": { - "version": "1.14.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", - "integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==" + "version": "1.14.7", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", + "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==" }, "forever-agent": { "version": "0.6.1", @@ -10428,6 +10062,13 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, "fstream": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", @@ -10498,9 +10139,9 @@ } }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -10537,9 +10178,9 @@ } }, "globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -10560,9 +10201,9 @@ }, "dependencies": { "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true } } @@ -10662,12 +10303,6 @@ "resolved": "https://registry.npmjs.org/helmet/-/helmet-4.3.1.tgz", "integrity": "sha512-WsafDyKsIexB0+pUNkq3rL1rB5GVAghR68TP8ssM9DPEMzfBiluEQlVzJ/FEj6Vq2Ag3CNuxf7aYMjXrN0X49Q==" }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", @@ -10734,14 +10369,6 @@ "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - } } }, "import-lazy": { @@ -10802,12 +10429,6 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, "is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -10817,6 +10438,15 @@ "has-bigints": "^1.0.1" } }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -10843,9 +10473,9 @@ } }, "is-core-module": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", - "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", "requires": { "has": "^1.0.3" } @@ -10872,9 +10502,9 @@ "dev": true }, "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -10891,9 +10521,9 @@ } }, "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true }, "is-npm": { @@ -10902,6 +10532,12 @@ "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, "is-number-object": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", @@ -10933,6 +10569,12 @@ "has-tostringtag": "^1.0.0" } }, + "is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -10967,6 +10609,15 @@ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, "is-yarn-global": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", @@ -11027,12 +10678,6 @@ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, "json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", @@ -11215,22 +10860,8 @@ "requires": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" - }, - "dependencies": { - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } } }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -11418,6 +11049,16 @@ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, "mime-db": { "version": "1.45.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", @@ -11475,32 +11116,32 @@ } }, "mocha": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.2.tgz", - "integrity": "sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.0.tgz", + "integrity": "sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.5.2", - "debug": "4.3.2", + "chokidar": "3.5.3", + "debug": "4.3.3", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.1.7", + "glob": "7.2.0", "growl": "1.10.5", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", "minimatch": "3.0.4", "ms": "2.1.3", - "nanoid": "3.1.25", + "nanoid": "3.2.0", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", "which": "2.0.2", - "workerpool": "6.1.5", + "workerpool": "6.2.0", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" @@ -11521,53 +11162,12 @@ "color-convert": "^2.0.1" } }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -11595,9 +11195,9 @@ "dev": true }, "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { "ms": "2.1.2" @@ -11617,15 +11217,6 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -11642,41 +11233,12 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "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 }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -11725,15 +11287,6 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -11743,15 +11296,6 @@ "has-flag": "^4.0.0" } }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -11914,9 +11458,9 @@ } }, "nanoid": { - "version": "3.1.25", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", - "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", + "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", "dev": true }, "natural-compare": { @@ -11953,47 +11497,6 @@ "update-notifier": "^5.1.0" }, "dependencies": { - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.0.tgz", - "integrity": "sha512-JgQM9JS92ZbFR4P90EvmzNpSGhpPBGBSj10PILeDyYFwp4h2/D9OM03wsJ4zW1fEp4ka2DGrnUeD7FuvQ2aZ2Q==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -12003,53 +11506,11 @@ "ms": "^2.1.1" } }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, "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 - }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } } } }, @@ -12062,18 +11523,6 @@ "abbrev": "1" } }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -12115,9 +11564,9 @@ "integrity": "sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==" }, "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", "dev": true }, "object-keys": { @@ -12139,14 +11588,14 @@ } }, "object.values": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", - "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" + "es-abstract": "^1.19.1" } }, "oidc-token-hash": { @@ -12441,6 +11890,12 @@ "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -12462,6 +11917,12 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "pause": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", @@ -12478,46 +11939,6 @@ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - } - } - }, - "pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - } - } - }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -12673,6 +12094,15 @@ "minimatch": "^3.0.4" } }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", @@ -12799,6 +12229,12 @@ "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz", "integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA==" }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, "responselike": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", @@ -12954,9 +12390,9 @@ "dev": true }, "shelljs": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", - "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", "requires": { "glob": "^7.0.0", "interpret": "^1.0.0", @@ -13046,38 +12482,6 @@ "memory-pager": "^1.0.2" } }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", - "dev": true - }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -13130,14 +12534,14 @@ } }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.1" } }, "string.prototype.trimend": { @@ -13169,6 +12573,12 @@ "ansi-regex": "^5.0.1" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -13190,23 +12600,22 @@ } }, "table": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", - "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", + "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", "dev": true, "requires": { "ajv": "^8.0.1", - "lodash.clonedeep": "^4.5.0", "lodash.truncate": "^4.4.2", "slice-ansi": "^4.0.0", - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0" + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" }, "dependencies": { "ajv": { - "version": "8.6.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", - "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -13215,12 +12624,6 @@ "uri-js": "^4.2.2" } }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -13310,6 +12713,15 @@ "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", "dev": true }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", @@ -13366,23 +12778,15 @@ } }, "tsconfig-paths": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", - "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", + "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", "dev": true, "requires": { "@types/json5": "^0.0.29", "json5": "^1.0.1", "minimist": "^1.2.0", "strip-bom": "^3.0.0" - }, - "dependencies": { - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } } }, "tslib": { @@ -13451,11 +12855,9 @@ } }, "typescript": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", - "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", - "dev": true, - "peer": true + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", + "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==" }, "uid-safe": { "version": "2.1.5", @@ -13746,16 +13148,6 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -13823,9 +13215,9 @@ "dev": true }, "workerpool": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", - "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", "dev": true }, "wrappy": { diff --git a/BackEnd/package.json b/BackEnd/package.json index a43aa53..dd4fe05 100644 --- a/BackEnd/package.json +++ b/BackEnd/package.json @@ -1,6 +1,6 @@ { "name": "essok-node", - "version": "1.5.3", + "version": "1.0.1", "description": "essok on node", "main": "app.ts", "scripts": { @@ -11,7 +11,7 @@ "node": "NODE_PATH=dist/ node -r dotenv/config dist/app.js", "nodemon": "NODE_PATH=src/ nodemon src/app.ts", "dev": "NODE_ENV=development DOTENV_CONFIG_PATH=.env-dev npm run nodemon", - "lint": "eslint {src,test}/**/*.ts --quiet", + "lint": "eslint src/**/*.ts --quiet", "mocha": "NODE_ENV=test NODE_PATH=src/ DOTENV_CONFIG_PATH=.env-test mocha", "test": "npm run mocha ./src/" }, @@ -43,6 +43,7 @@ "passport-local": "1.0.0", "rimraf": "^3.0.2", "slug": "4.0.2", + "typescript": "^4.5.4", "unzipper": "^0.10.11" }, "devDependencies": { @@ -52,13 +53,13 @@ "@types/mocha": "^9.0.0", "@types/morgan": "^1.9.3", "@types/node": "^17.0.5", - "@typescript-eslint/eslint-plugin": "^4.28.4", - "@typescript-eslint/parser": "^4.28.4", - "eslint": "^7.31.0", + "@typescript-eslint/eslint-plugin": "^5.9.0", + "@typescript-eslint/parser": "^5.9.0", + "eslint": "^7.12.1", "eslint-config-standard": "^16.0.3", - "eslint-plugin-import": "^2.23.4", + "eslint-plugin-import": "^2.25.4", "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^5.1.0", + "eslint-plugin-promise": "^5.0.0", "mocha": "^9.1.2", "nodemon": "^2.0.13", "ts-node": "^10.2.1" diff --git a/BackEnd/src/cloud/CloudService.ts b/BackEnd/src/cloud/CloudService.ts index f90e0d1..53ccce2 100644 --- a/BackEnd/src/cloud/CloudService.ts +++ b/BackEnd/src/cloud/CloudService.ts @@ -2,61 +2,64 @@ import path from 'path' import { DataKind, - dirToFileOutput, InputData as ObjectData, + outPathData, OutputData as ObjectDataOptions } from 'utils/Data' export type ContainerName = string export type ObjectName = string -export interface CloudService { - listContainers(): Promise - createContainer(name: ContainerName): Promise - deleteContainer(name: ContainerName): Promise - - listObjects(name: ContainerName): Promise - downloadObject(cName: ContainerName, oName: ObjectName, - oOptions: ObjectDataOptions): Promise - uploadObject(cName: ContainerName, - oName: ObjectName, oData: ObjectData): Promise - deleteObject(cName: ContainerName, oName: ObjectName): Promise -} +export abstract class CloudService { + abstract listContainers(): Promise + abstract createContainer(name: ContainerName): Promise + abstract deleteContainer(name: ContainerName): Promise -type ApplyFun = (oName: string, index: number) => Promise -async function applyObjects(cloud: CloudService, cName: ContainerName, - apply: ApplyFun) -: Promise { - const oNames = await cloud.listObjects(cName) - return Promise.all(oNames.map(apply)) -} + abstract listObjects(name: ContainerName): Promise + abstract downloadObject(cName: ContainerName, oName: ObjectName, + oOptions: ObjectDataOptions): Promise -type DirectoryDataOption = ObjectDataOptions -export type AllObjsDataOptions = DirectoryDataOption | ObjectDataOptions[] -export async function downloadObjects(cloud: CloudService, - cName: ContainerName, - oOptions: AllObjsDataOptions) -: Promise { - const applyFun = (oName: string, objiOptions: ObjectDataOptions) => - cloud.downloadObject(cName, oName, objiOptions) - const applyFunOptions = (Array.isArray(oOptions)) ? - (oName: string, i: number) => applyFun(oName, oOptions[i]) - : (oName: string) => applyFun(oName, dirToFileOutput(oOptions, oName)) - - return applyObjects(cloud, cName, applyFunOptions) -} + abstract uploadObject(cName: ContainerName, + oName: ObjectName, oData: ObjectData): Promise -export async function copyObjects(cloud: CloudService, - cNameSrc: ContainerName, - cNameDst: ContainerName): Promise { - await applyObjects(cloud, cNameSrc, async (oName: string) => { - const objBufferData = - await cloud.downloadObject(cNameSrc, oName, { kind: DataKind.Buffer }) - await cloud.uploadObject(cNameDst, oName, objBufferData) - }) -} + abstract deleteObject(cName: ContainerName, oName: ObjectName): Promise + + /** + * Generic function used in the next functions + */ + private async _applyObjects (cName: ContainerName, + apply: (oName: string) => Promise): Promise { + const oNames = await this.listObjects(cName) + return Promise.all(oNames.map(apply)) + } + + /** + * If downloading to a list of Path, oOptions expect a directory + */ + async downloadAllObjs (cName: ContainerName, + oOptions: ObjectDataOptions): Promise { + switch (oOptions.kind) { + case DataKind.Buffer: + return this._applyObjects(cName, (oName: string) => + this.downloadObject(cName, oName, oOptions)) + case DataKind.Path: + return this._applyObjects(cName, (oName: string) => { + const oOptionsWithDir = outPathData(path.join(oOptions.output, oName)) + return this.downloadObject(cName, oName, oOptionsWithDir) + }) + } + } + + async copyObjects (cNameSrc: ContainerName, + cNameDst: ContainerName): Promise { + await this._applyObjects(cNameSrc, async (oName: string) => { + const objBufferData = + await this.downloadObject(cNameSrc, oName, { kind: DataKind.Buffer }) + await this.uploadObject(cNameDst, oName, objBufferData) + }) + } -export async function deleteObjects(cloud: CloudService, - cName: ContainerName): Promise { - await applyObjects(cloud, cName, oName => cloud.deleteObject(cName, oName)) + async deleteObjects (cName: ContainerName): Promise { + await this._applyObjects(cName, oName => this.deleteObject(cName, oName)) + } } diff --git a/BackEnd/src/cloud/SwiftService.spec.ts b/BackEnd/src/cloud/SwiftService.spec.ts index 31dcd2b..9c8b5ba 100644 --- a/BackEnd/src/cloud/SwiftService.spec.ts +++ b/BackEnd/src/cloud/SwiftService.spec.ts @@ -22,8 +22,8 @@ describe('SwiftService', function () { it('should set token and cloudUrl', async function () { const service = new SwiftService({ updateOnce: true }) await service.init() - assert.ok(service.token) - assert.ok(service.cloudUrl) + + assert.equal(service.success, true) }) }) }) @@ -35,9 +35,9 @@ describe('SwiftService', function () { }) describe('Container', function () { - const lsName = 'list' - const crName = 'creation' - const dlName = 'deletion' + const lsName = 'test-list' + const crName = 'test-creation' + const dlName = 'test-deletion' describe('listContainers()', function () { it('should return list of containers', async function () { @@ -74,13 +74,13 @@ describe('SwiftService', function () { }) describe('Objects from container', function () { - const cName = 'objects' - const lsOName = 'listObj' - const dlOName = 'dlObj' - const dlOData = 'data' - const crOName = 'creationObj' - const crOData = 'cData' - const delOName = 'deletionObj' + const cName = 'test-objects' + const lsOName = 'listObject' + const ddlOName = 'downloadObject' + const ddlOData = 'downloadData' + const crOName = 'creationObject' + const crOData = 'creationData' + const dlOName = 'deletionObject' const options: OutputData = { kind: DataKind.Buffer } @@ -91,10 +91,10 @@ describe('SwiftService', function () { }) }) - describe(`downloadObject(${cName}, ${dlOName})`, function () { - it(`should return the data of object ${dlOName}`, async function () { - const buffer = await service.downloadObject(cName, dlOName, options) - assert.equal(buffer.input.toString(), dlOData) + describe(`downloadObject(${cName}, ${ddlOName})`, function () { + it(`should return the data of object ${ddlOName}`, async function () { + const buffer = await service.downloadObject(cName, ddlOName, options) + assert.equal(buffer.input.toString(), ddlOData) }) }) @@ -110,19 +110,19 @@ describe('SwiftService', function () { }) }) - describe(`deleteObject(${cName}, ${delOName})`, function () { + describe(`deleteObject(${cName}, ${dlOName})`, function () { beforeEach(async function () { const oData: InputData = { kind: DataKind.Buffer, input: Buffer.from('') } - await service.uploadObject(cName, delOName, oData) + await service.uploadObject(cName, dlOName, oData) }) - it(`should delete object named ${delOName}`, async function () { - await service.deleteObject(cName, delOName) + it(`should delete object named ${dlOName}`, async function () { + await service.deleteObject(cName, dlOName) const objects = await service.listObjects(cName) - assert(!objects.includes(delOName)) + assert(!objects.includes(dlOName)) }) }) }) diff --git a/BackEnd/src/cloud/SwiftService.ts b/BackEnd/src/cloud/SwiftService.ts index 0168f2d..1be622c 100644 --- a/BackEnd/src/cloud/SwiftService.ts +++ b/BackEnd/src/cloud/SwiftService.ts @@ -4,9 +4,11 @@ import fs from 'fs' import env from 'env' import { DataKind as ObjectDataKind, + BufferInputData as BufferObjectData, InputData as ObjectData, OutputData as ObjectDataOptions, - bufferFromData + convertData, + outBufferData } from 'utils/Data' import { CloudService, ContainerName, ObjectName } from './CloudService' import * as auth from './swift/SWIFTAUTH' @@ -15,17 +17,25 @@ import { SwiftError, SwiftErrorType } from './swift/SwiftError' type Token = string type UrlService = string -export class SwiftService implements CloudService { - token!: Token - cloudUrl!: UrlService - updateSuccess!: boolean - readonly updateOnce!: boolean +export class SwiftService extends CloudService { + private token!: Token + private cloudUrl!: UrlService + private updateSuccess!: boolean + private readonly updateOnce!: boolean constructor ({ updateOnce } = { updateOnce: false }) { + super() this.updateSuccess = false this.updateOnce = updateOnce } + /** + * Used for tests + */ + get success () { + return this.updateSuccess + } + async init (): Promise { return this.updateCredentials() } @@ -142,7 +152,7 @@ export class SwiftService implements CloudService { responseType: 'arraybuffer' }) - switch(oOptions.kind) { + switch (oOptions.kind) { case ObjectDataKind.Buffer: return { kind: ObjectDataKind.Buffer, input: res.data } case ObjectDataKind.Path: @@ -159,7 +169,7 @@ export class SwiftService implements CloudService { baseURL: this.cloudUrl, url: `/${cName}/${oName}`, headers: { 'X-Auth-Token': this.token }, - data: bufferFromData(oData) + data: (convertData(oData, outBufferData) as BufferObjectData).input }) } diff --git a/BackEnd/src/cloud/swift/SwiftError.ts b/BackEnd/src/cloud/swift/SwiftError.ts index 544b721..e79b240 100644 --- a/BackEnd/src/cloud/swift/SwiftError.ts +++ b/BackEnd/src/cloud/swift/SwiftError.ts @@ -7,17 +7,17 @@ export enum SwiftErrorType { export class SwiftError extends Error { constructor (errorType: SwiftErrorType) { switch (errorType) { - case SwiftErrorType.ServiceNotFound: - super('cloud service is not listed in the catalog') - this.name = 'ServiceNotFoundError' - break - case SwiftErrorType.RegionNotFound: - super('region of the cloud service is not listed in the catalog') - this.name = 'RegionNotFoundError' - break - case SwiftErrorType.ServiceIsUnavailable: - super('cloud service is unavailable until next update attempt') - this.name = 'ServiceIsUnavailableError' + case SwiftErrorType.ServiceNotFound: + super('cloud service is not listed in the catalog') + this.name = 'ServiceNotFoundError' + break + case SwiftErrorType.RegionNotFound: + super('region of the cloud service is not listed in the catalog') + this.name = 'RegionNotFoundError' + break + case SwiftErrorType.ServiceIsUnavailable: + super('cloud service is unavailable until next update attempt') + this.name = 'ServiceIsUnavailableError' } } } diff --git a/BackEnd/src/controllers/index.ts b/BackEnd/src/controllers/index.ts index 4eaa083..4b2ae36 100644 --- a/BackEnd/src/controllers/index.ts +++ b/BackEnd/src/controllers/index.ts @@ -9,7 +9,7 @@ export function api (cloud: CloudService) { const router = Router() /* TODO: use ES6 import */ router.use(userAPI(cloud)) - router.use('/profiles', require('./profiles')) + router.use('/profiles', require('./profiles')) // eslint-disable-line router.use('/servers', serverAPI(cloud)) router.use('/uploads', uploadAPI(cloud)) diff --git a/BackEnd/src/controllers/server.ts b/BackEnd/src/controllers/server.ts index b929d7e..02089e5 100644 --- a/BackEnd/src/controllers/server.ts +++ b/BackEnd/src/controllers/server.ts @@ -12,11 +12,7 @@ import log_message from '../configs/log_message'; import env from 'env' import { Server, User } from 'models' -import { - CloudService, - copyObjects, - deleteObjects -} from 'cloud/CloudService'; +import { CloudService } from 'cloud/CloudService'; export function serverAPI(cloud: CloudService) { const router = Router(); @@ -98,7 +94,7 @@ export function serverAPI(cloud: CloudService) { log_functions.create('bin', 'post /server/', log_message.user_server_created, user, server); return server.save().then(async function() { await cloud.createContainer(server.slug) - await copyObjects(cloud, env.OS_DEFAULT_CONTAINER, server.slug) + await cloud.copyObjects(env.OS_DEFAULT_CONTAINER, server.slug) log_functions.create('general', 'post /server/', log_message.user_swift_created, user, server); @@ -308,7 +304,7 @@ export function serverAPI(cloud: CloudService) { await server_functions.removekubelink(slug, namespace) console.log('kubelink removed') - await deleteObjects(cloud, slug) + await cloud.deleteObjects(slug) await cloud.deleteContainer(slug) console.log('swift container removed') diff --git a/BackEnd/src/controllers/upload.ts b/BackEnd/src/controllers/upload.ts index d4769f5..7ca4be6 100644 --- a/BackEnd/src/controllers/upload.ts +++ b/BackEnd/src/controllers/upload.ts @@ -10,8 +10,8 @@ import * as upload_functions from '../lib/upload_functions'; import upload_errors from '../lib/errors'; import api_code from '../configs/api_code'; -import { CloudService, downloadObjects } from 'cloud/CloudService'; -import { DataKind } from 'utils/Data'; +import { CloudService } from 'cloud/CloudService'; +import { DataKind, outPathData } from 'utils/Data'; const dirPath = './uploads/'; var destPath = ''; @@ -445,10 +445,8 @@ export function uploadAPI(cloud: CloudService) { .catch((err: any) => upload_errors.wrap_error('createArbo', api_code.error, err)) if(target === 'all') { - await downloadObjects(cloud, server.slug, { - kind: DataKind.Path, - output: path.join(dest_path, download_folder) - }) + const downloadPath = path.join(dest_path, download_folder) + await cloud.downloadAllObjs(server.slug, outPathData(downloadPath)) } else { const targetArchive = target + '.zip' await cloud.downloadObject(server.slug, targetArchive, { diff --git a/BackEnd/src/controllers/users.ts b/BackEnd/src/controllers/users.ts index 934c9b5..c89f030 100644 --- a/BackEnd/src/controllers/users.ts +++ b/BackEnd/src/controllers/users.ts @@ -10,7 +10,7 @@ import * as global_functions from '../lib/global_functions'; import api_code from '../configs/api_code'; -import { CloudService, deleteObjects } from 'cloud/CloudService' +import { CloudService } from 'cloud/CloudService' import { User } from 'models' // can delegate cloud API call to serverAPI ? @@ -347,7 +347,7 @@ export function userAPI(cloud: CloudService) { await server_functions.removekubelink(server.slug, namespace) console.log('kubelink removed') - await deleteObjects(cloud, server.slug) + await cloud.deleteObjects(server.slug) console.log('swift container removed') const serverDir = diff --git a/BackEnd/src/env/utils.ts b/BackEnd/src/env/utils.ts index 41a5bcd..c40cd50 100644 --- a/BackEnd/src/env/utils.ts +++ b/BackEnd/src/env/utils.ts @@ -1,11 +1,11 @@ export function ownDefault ({ dev, test, all }: {dev: T, test: T, all: T}) { switch (process.env.NODE_ENV) { - case 'test': - return test - case 'development': - return dev - default: - return all + case 'test': + return test + case 'development': + return dev + default: + return all } } diff --git a/BackEnd/src/utils/Data.ts b/BackEnd/src/utils/Data.ts index bc11020..a874e84 100644 --- a/BackEnd/src/utils/Data.ts +++ b/BackEnd/src/utils/Data.ts @@ -1,56 +1,57 @@ -import { readFileSync } from 'fs' +import fs from 'fs' import path from 'path' export type Path = string export const enum DataKind { Buffer, - Path, + Path } -export type InputData = - | { kind: DataKind.Buffer, - input: Buffer } - | { kind: DataKind.Path, - input: Path } +export type BufferInputData = { kind: DataKind.Buffer, input: Buffer } +export type PathInputData = { kind: DataKind.Path, input: Path } +export type InputData = BufferInputData | PathInputData -export type OutputData = - | { kind: DataKind.Buffer } - | { kind: DataKind.Path, - output: Path } +export type BufferOutputData = { kind: DataKind.Buffer } +export type PathOutputData = { kind: DataKind.Path, output: Path } +export type OutputData = BufferOutputData | PathOutputData -export function bufferFromData (iData: InputData): Buffer { - switch(iData.kind) { - case DataKind.Buffer: - return iData.input - case DataKind.Path: - return readFileSync(iData.input) - } +export function inBufferData (input: Buffer) : BufferInputData { + return { kind: DataKind.Buffer, input } +} +export function inPathData (input: Path) : PathInputData { + return { kind: DataKind.Path, input } } -/** - * Append filename to directory path (from a Path kind of InputData) - */ -export function dirToFileInput(dirData: InputData, filename: string) { - switch(dirData.kind) { - case DataKind.Buffer: - return dirData - case DataKind.Path: - return { - ...dirData, - input: path.join(dirData.input, filename) - } - } +export const outBufferData: OutputData = { kind: DataKind.Buffer } +export function outPathData (output: Path) : OutputData { + return { kind: DataKind.Path, output } } -export function dirToFileOutput(dirData: OutputData, filename: string) { - switch(dirData.kind) { +export function convertData (iData: InputData, oData: OutputData) : InputData { + switch (iData.kind) { case DataKind.Buffer: - return dirData + switch (oData.kind) { + case DataKind.Buffer: + return iData + case DataKind.Path: + fs.mkdirSync(path.dirname(oData.output), { recursive: true }) + fs.writeFileSync(oData.output, iData.input) + return { kind: DataKind.Path, input: oData.output } + } + // break omitted as we are unreachable here (comment for eslint rule) case DataKind.Path: - return { - ...dirData, - output: path.join(dirData.output, filename) + switch (oData.kind) { + case DataKind.Buffer: + return { kind: DataKind.Buffer, input: fs.readFileSync(iData.input) } + case DataKind.Path: + if (iData.input !== oData.output) { + fs.mkdirSync(path.dirname(oData.output), { recursive: true }) + fs.copyFileSync(iData.input, oData.output) + return { kind: DataKind.Path, input: oData.output } + } else { + return iData + } } } } From d51132aade8b8ce8a73d3021b24d9e0a368d6767 Mon Sep 17 00:00:00 2001 From: Astyax NOUREL Date: Sun, 17 Oct 2021 20:26:25 +0200 Subject: [PATCH 2/6] adding own archive service cleaning upload controller partial lint of src/controllers/upload.ts removed useless variable in server-settings in Frontend removing packages: - archiver - child_process - express-session & @types - fs-readdir-recursive - fs-extra - rimraf - unzipper --- BackEnd/.eslintignore | 8 +- BackEnd/assets/archive.zip | Bin 0 -> 355 bytes BackEnd/assets/archiveDir/archiveFile | 1 + BackEnd/package-lock.json | 1676 ++++------------- BackEnd/package.json | 16 +- BackEnd/src/app.ts | 14 +- BackEnd/src/archive/AdmZipService.spec.ts | 61 + BackEnd/src/archive/AdmZipService.ts | 72 + BackEnd/src/archive/ArchiveService.ts | 47 + BackEnd/src/controllers/index.ts | 27 +- BackEnd/src/controllers/profiles.ts | 75 +- BackEnd/src/controllers/server.ts | 716 ++++--- BackEnd/src/controllers/upload.ts | 846 ++++----- BackEnd/src/controllers/users.ts | 675 +++---- BackEnd/src/lib/errors.ts | 58 - BackEnd/src/lib/upload_functions.ts | 670 ------- BackEnd/src/middlewares/index.ts | 15 +- BackEnd/src/middlewares/session.ts | 8 - FrontEnd/package-lock.json | 23 +- .../src/app/core/services/servers.service.ts | 6 +- .../server-settings.component.ts | 49 +- 21 files changed, 1690 insertions(+), 3373 deletions(-) create mode 100644 BackEnd/assets/archive.zip create mode 100644 BackEnd/assets/archiveDir/archiveFile create mode 100644 BackEnd/src/archive/AdmZipService.spec.ts create mode 100644 BackEnd/src/archive/AdmZipService.ts create mode 100644 BackEnd/src/archive/ArchiveService.ts delete mode 100644 BackEnd/src/lib/errors.ts delete mode 100644 BackEnd/src/lib/upload_functions.ts delete mode 100644 BackEnd/src/middlewares/session.ts diff --git a/BackEnd/.eslintignore b/BackEnd/.eslintignore index 8714536..d8781b2 100644 --- a/BackEnd/.eslintignore +++ b/BackEnd/.eslintignore @@ -5,7 +5,7 @@ src/configs/**/*.ts src/lib/**/*.ts src/models/*.ts src/controllers/auth.ts -src/controllers/users.ts -src/controllers/profiles.ts -src/controllers/server.ts -src/controllers/upload.ts +#src/controllers/users.ts +#src/controllers/profiles.ts +#src/controllers/server.ts +#src/controllers/upload.ts diff --git a/BackEnd/assets/archive.zip b/BackEnd/assets/archive.zip new file mode 100644 index 0000000000000000000000000000000000000000..5d5b3c6d1a24727443e746476eb54bceb038ad23 GIT binary patch literal 355 zcmWIWW@h1H00HMR)etZPN^mpCFeDZwXJnS8x?~pVhlX%6F!L?Cns|KK)x^>YZU#n{ z7t9O{U?Ko+hz`&Y5A)^=+(1J>SPaz=sCjOgIjLat9xuF_SiS_qJeakKC5Zvvj7)OO zxLha!b*liwTSpKRrV;F3R)~8s+=?&|)3p!-8G%MEX>>(35XJ34vq5ghFq@SP=0.4.0" } }, + "node_modules/adm-zip": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz", + "integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==", + "engines": { + "node": ">=6.0" + } + }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -995,65 +1017,6 @@ "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" }, - "node_modules/archiver": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.2.0.tgz", - "integrity": "sha512-QEAKlgQuAtUxKeZB9w5/ggKXh21bZS+dzzuQ0RPBC20qtDCbTyzqmisoeJP46MP39fg4B4IcyvR+yeyEBdblsQ==", - "dependencies": { - "archiver-utils": "^2.1.0", - "async": "^3.2.0", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", - "readdir-glob": "^1.0.0", - "tar-stream": "^2.1.4", - "zip-stream": "^4.0.4" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dependencies": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/archiver-utils/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/archiver-utils/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_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -1069,9 +1032,9 @@ } }, "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-3.0.0.tgz", + "integrity": "sha512-zPMVc3ZYlGLNk4mpK1NzP2wg0ml9t7fUgDsayR5Y5rSzxQilzR9FGu/EH2jQOcKSAeAfWeylyW8juy3OkWRvNA==" }, "node_modules/array-includes": { "version": "3.1.4", @@ -1143,24 +1106,11 @@ "node": ">=8" } }, - "node_modules/async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -1233,26 +1183,6 @@ "tweetnacl": "^0.14.3" } }, - "node_modules/big-integer": { - "version": "1.6.48", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", - "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/binary": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", - "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", - "dependencies": { - "buffers": "~0.1.1", - "chainsaw": "~0.1.0" - }, - "engines": { - "node": "*" - } - }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -1263,23 +1193,23 @@ } }, "node_modules/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "version": "2.0.0-beta.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.0.0-beta.1.tgz", + "integrity": "sha512-I1v2bt2OdYqtmk8nEFZuEf+9Opb30DphYwTPDbgg/OorSAoJOuTpWyDrZaSWQw7FdoevbBRCP2+9z/halXSWcA==", "dependencies": { - "bytes": "3.1.0", + "bytes": "3.1.1", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "~1.1.2", - "http-errors": "1.7.2", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "qs": "6.9.6", + "raw-body": "2.4.2", + "type-is": "~1.6.18" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.10" } }, "node_modules/boxen": { @@ -1452,14 +1382,6 @@ "ieee754": "^1.1.13" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "engines": { - "node": "*" - } - }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -1470,22 +1392,6 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, - "node_modules/buffer-indexof-polyfill": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", - "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/buffers": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", - "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", - "engines": { - "node": ">=0.2.0" - } - }, "node_modules/busboy": { "version": "0.2.14", "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", @@ -1528,9 +1434,9 @@ } }, "node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", + "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", "engines": { "node": ">= 0.8" } @@ -1613,17 +1519,6 @@ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, - "node_modules/chainsaw": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", - "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", - "dependencies": { - "traverse": ">=0.3.0 <0.4" - }, - "engines": { - "node": "*" - } - }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -1638,11 +1533,6 @@ "node": ">=4" } }, - "node_modules/child_process": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz", - "integrity": "sha1-sffn/HPSXn/R1FWtyU4UODAYK1o=" - }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -1738,20 +1628,6 @@ "node": ">= 0.8" } }, - "node_modules/compress-commons": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.0.2.tgz", - "integrity": "sha512-qhd32a9xgzmpfoga1VQEiLEwdKZ6Plnpx5UCgIsf89FSolyJ7WnifY4Gtjgv5WR6hWAyRaHxC5MiEhU/38U70A==", - "dependencies": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^4.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1794,16 +1670,35 @@ } }, "node_modules/content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dependencies": { - "safe-buffer": "5.1.2" + "safe-buffer": "5.2.1" }, "engines": { "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.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -1813,9 +1708,9 @@ } }, "node_modules/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "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" } @@ -1842,33 +1737,6 @@ "node": ">= 0.10" } }, - "node_modules/crc-32": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", - "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", - "dependencies": { - "exit-on-epipe": "~1.0.1", - "printj": "~1.1.0" - }, - "bin": { - "crc32": "bin/crc32.njs" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/crc32-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.1.tgz", - "integrity": "sha512-FN5V+weeO/8JaXsamelVYO1PHyeCsuL3HcG4cqsj0ceARcocxalaShCsohZMSAF+db7UYFwBy1rARK/0oFItUw==", - "dependencies": { - "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -2071,36 +1939,6 @@ "node": ">=10" } }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dependencies": { - "readable-stream": "^2.0.2" - } - }, - "node_modules/duplexer2/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/duplexer2/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_modules/duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -2924,27 +2762,19 @@ "which": "bin/which" } }, - "node_modules/exit-on-epipe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", - "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", - "engines": { - "node": ">=0.8" - } - }, "node_modules/express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "version": "5.0.0-beta.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.0.0-beta.1.tgz", + "integrity": "sha512-KPtBrlZoQu2Ps0Ce/Imqtq73AB0KBJ8Gx59yZQ3pmDJU2/LhcoZETo03oSgtTQufbcLXt/WBITk/jMjl/WMyrQ==", "dependencies": { "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", + "array-flatten": "3.0.0", + "body-parser": "2.0.0-beta.1", + "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.0", + "cookie": "0.4.1", "cookie-signature": "1.0.6", - "debug": "2.6.9", + "debug": "3.1.0", "depd": "~1.1.2", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -2953,23 +2783,25 @@ "fresh": "0.5.2", "merge-descriptors": "1.0.1", "methods": "~1.1.2", + "mime-types": "~2.1.34", "on-finished": "~2.3.0", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", + "path-is-absolute": "1.0.1", + "proxy-addr": "~2.0.7", + "qs": "6.9.6", "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", + "router": "2.0.0-beta.1", + "safe-buffer": "5.2.1", + "send": "1.0.0-beta.1", + "serve-static": "2.0.0-beta.1", + "setprototypeof": "1.2.0", "statuses": "~1.5.0", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "engines": { - "node": ">= 0.10.0" + "node": ">= 4" } }, "node_modules/express-jwt": { @@ -2991,41 +2823,20 @@ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" }, - "node_modules/express-session": { - "version": "1.17.2", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", - "integrity": "sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ==", - "dependencies": { - "cookie": "0.4.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-headers": "~1.0.2", - "parseurl": "~1.3.3", - "safe-buffer": "5.2.1", - "uid-safe": "~2.1.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/express-session/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/express-unless": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/express-unless/-/express-unless-0.3.1.tgz", + "integrity": "sha1-JVfBRudb65A+LSR/m1ugFFJpbiA=" }, - "node_modules/express-session/node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" + "node_modules/express/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dependencies": { + "ms": "2.0.0" } }, - "node_modules/express-session/node_modules/safe-buffer": { + "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==", @@ -3044,11 +2855,6 @@ } ] }, - "node_modules/express-unless": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/express-unless/-/express-unless-0.3.1.tgz", - "integrity": "sha1-JVfBRudb65A+LSR/m1ugFFJpbiA=" - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -3179,9 +2985,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.14.7", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", - "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", + "version": "1.14.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", + "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==", "funding": [ { "type": "individual", @@ -3219,9 +3025,9 @@ } }, "node_modules/forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "engines": { "node": ">= 0.6" } @@ -3234,25 +3040,6 @@ "node": ">= 0.6" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "node_modules/fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -3264,11 +3051,6 @@ "node": ">= 8" } }, - "node_modules/fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==" - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3288,31 +3070,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "dependencies": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - }, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/fstream/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -3499,7 +3256,8 @@ "node_modules/graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true }, "node_modules/growl": { "version": "1.10.5", @@ -3619,25 +3377,20 @@ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, "node_modules/http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "dependencies": { "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "toidentifier": "1.0.1" }, "engines": { "node": ">= 0.6" } }, - "node_modules/http-errors/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, "node_modules/http2-wrapper": { "version": "1.0.0-beta.5.2", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz", @@ -4171,25 +3924,6 @@ "json5": "lib/cli.js" } }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonfile/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/jsonpath-plus": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-0.19.0.tgz", @@ -4282,39 +4016,6 @@ "node": ">=8" } }, - "node_modules/lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dependencies": { - "readable-stream": "^2.0.5" - }, - "engines": { - "node": ">= 0.6.3" - } - }, - "node_modules/lazystream/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/lazystream/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_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -4328,11 +4029,6 @@ "node": ">= 0.8.0" } }, - "node_modules/listenercount": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", - "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=" - }, "node_modules/locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", @@ -4346,21 +4042,6 @@ "node": ">=4" } }, - "node_modules/lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" - }, - "node_modules/lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" - }, - "node_modules/lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" - }, "node_modules/lodash.foreach": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", @@ -4422,11 +4103,6 @@ "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", "dev": true }, - "node_modules/lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" - }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -4587,19 +4263,19 @@ } }, "node_modules/mime-db": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", - "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.28", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", - "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "dependencies": { - "mime-db": "1.45.0" + "mime-db": "1.51.0" }, "engines": { "node": ">= 0.6" @@ -5223,6 +4899,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -5741,9 +5418,9 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.2.0.tgz", + "integrity": "sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==" }, "node_modules/path-type": { "version": "4.0.0", @@ -5794,17 +5471,6 @@ "node": ">=4" } }, - "node_modules/printj": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", - "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==", - "bin": { - "printj": "bin/printj.njs" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -5820,11 +5486,11 @@ } }, "node_modules/proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dependencies": { - "forwarded": "~0.1.2", + "forwarded": "0.2.0", "ipaddr.js": "1.9.1" }, "engines": { @@ -5872,11 +5538,14 @@ } }, "node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", "engines": { "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/queue-microtask": { @@ -5910,14 +5579,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/random-bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", - "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -5936,12 +5597,12 @@ } }, "node_modules/raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", + "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.2", + "bytes": "3.1.1", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, @@ -5973,27 +5634,6 @@ "node": ">=0.10.0" } }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdir-glob": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.1.tgz", - "integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==", - "dependencies": { - "minimatch": "^3.0.4" - } - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -6217,6 +5857,22 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/router": { + "version": "2.0.0-beta.1", + "resolved": "https://registry.npmjs.org/router/-/router-2.0.0-beta.1.tgz", + "integrity": "sha512-GLoYgkhAGAiwVda5nt6Qd4+5RAPuQ4WIYLlZ+mxfYICI+22gnIB3eCfmhgV8+uJNPS1/39DOYi/vdrrz0/ouKA==", + "dependencies": { + "array-flatten": "3.0.0", + "methods": "~1.1.2", + "parseurl": "~1.3.3", + "path-to-regexp": "3.2.0", + "setprototypeof": "1.2.0", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -6292,43 +5948,44 @@ } }, "node_modules/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.0.0-beta.1.tgz", + "integrity": "sha512-OKTRokcl/oo34O8+6aUpj8Jf2Bjw2D0tZzmX0/RvyfVC9ZOZW+HPAWAlhS817IsRaCnzYX1z++h2kHFr2/KNRg==", "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", + "debug": "3.1.0", "destroy": "~1.0.4", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", + "http-errors": "1.8.1", + "mime-types": "~2.1.34", + "ms": "2.1.3", "on-finished": "~2.3.0", "range-parser": "~1.2.1", "statuses": "~1.5.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.10" } }, - "node_modules/send/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" + "node_modules/send/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dependencies": { + "ms": "2.0.0" } }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "node_modules/send/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/serialize-javascript": { "version": "6.0.0", @@ -6340,28 +5997,23 @@ } }, "node_modules/serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "version": "2.0.0-beta.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.0.0-beta.1.tgz", + "integrity": "sha512-DEJ9on/tQeFO2Omj7ovT02lCp1YgP4Kb8W2lv2o/4keTFAbgc8HtH3yPd47++2wv9lvQeqiA7FHFDe5+8c4XpA==", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.1" + "send": "1.0.0-beta.1" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.10" } }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, "node_modules/setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "node_modules/shebang-command": { "version": "2.0.0", @@ -6555,33 +6207,6 @@ "node": ">=0.8.0" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string_decoder/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/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -6729,54 +6354,6 @@ "node": ">= 10" } }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar-stream/node_modules/bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/tar-stream/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/tar/node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -6835,9 +6412,9 @@ } }, "node_modules/toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "engines": { "node": ">=0.6" } @@ -6865,14 +6442,6 @@ "node": ">=12" } }, - "node_modules/traverse": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", - "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", - "engines": { - "node": "*" - } - }, "node_modules/ts-node": { "version": "10.2.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", @@ -7036,17 +6605,6 @@ "node": ">=4.2.0" } }, - "node_modules/uid-safe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", - "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", - "dependencies": { - "random-bytes": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/unbox-primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", @@ -7076,14 +6634,6 @@ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" }, - "node_modules/universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -7092,50 +6642,6 @@ "node": ">= 0.8" } }, - "node_modules/unzipper": { - "version": "0.10.11", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", - "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", - "dependencies": { - "big-integer": "^1.6.17", - "binary": "~0.3.0", - "bluebird": "~3.4.1", - "buffer-indexof-polyfill": "~1.0.0", - "duplexer2": "~0.1.4", - "fstream": "^1.0.12", - "graceful-fs": "^4.2.2", - "listenercount": "~1.0.1", - "readable-stream": "~2.3.6", - "setimmediate": "~1.0.4" - } - }, - "node_modules/unzipper/node_modules/bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=" - }, - "node_modules/unzipper/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/unzipper/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_modules/update-notifier": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", @@ -7585,19 +7091,6 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/zip-stream": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.0.4.tgz", - "integrity": "sha512-a65wQ3h5gcQ/nQGWV1mSZCEzCML6EK/vyVPcrPNynySP1j3VBbQKh3nhC8CbORb+jfl2vXvh56Ul5odP1bAHqw==", - "dependencies": { - "archiver-utils": "^2.1.0", - "compress-commons": "^4.0.2", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">= 10" - } } }, "dependencies": { @@ -7814,6 +7307,15 @@ "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", "dev": true }, + "@types/adm-zip": { + "version": "0.4.34", + "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.4.34.tgz", + "integrity": "sha512-8ToYLLAYhkRfcmmljrKi22gT2pqu7hGMDtORP1emwIEGmgUTZOsaDjzWFzW5N2frcFRz/50CWt4zA1CxJ73pmQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/body-parser": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz", @@ -7878,15 +7380,6 @@ "@types/range-parser": "*" } }, - "@types/express-session": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.4.tgz", - "integrity": "sha512-7cNlSI8+oOBUHTfPXMwDxF/Lchx5aJ3ho7+p9jJZYVg9dVDJFh3qdMXmJtRsysnvS+C6x46k9DRYmrmCkE+MVg==", - "dev": true, - "requires": { - "@types/express": "*" - } - }, "@types/http-cache-semantics": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz", @@ -7946,11 +7439,29 @@ "@types/node": "*" } }, + "@types/multer": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.7.tgz", + "integrity": "sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA==", + "dev": true, + "requires": { + "@types/express": "*" + } + }, "@types/node": { "version": "17.0.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.5.tgz", "integrity": "sha512-w3mrvNXLeDYV1GKTZorGJQivK6XLCoGwpnyJFbJVK/aTBQUxOCaa/GlFAAN3OTDFcb7h5tiFG+YXCO2By+riZw==" }, + "@types/passport": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.7.tgz", + "integrity": "sha512-JtswU8N3kxBYgo+n9of7C97YQBT+AYPP2aBfNGTzABqPAZnK/WOAaKfh3XesUYMZRrXFuoPc2Hv0/G/nQFveHw==", + "dev": true, + "requires": { + "@types/express": "*" + } + }, "@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", @@ -8276,6 +7787,11 @@ "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true }, + "adm-zip": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz", + "integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==" + }, "aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -8335,61 +7851,6 @@ "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" }, - "archiver": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.2.0.tgz", - "integrity": "sha512-QEAKlgQuAtUxKeZB9w5/ggKXh21bZS+dzzuQ0RPBC20qtDCbTyzqmisoeJP46MP39fg4B4IcyvR+yeyEBdblsQ==", - "requires": { - "archiver-utils": "^2.1.0", - "async": "^3.2.0", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", - "readdir-glob": "^1.0.0", - "tar-stream": "^2.1.4", - "zip-stream": "^4.0.4" - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -8405,9 +7866,9 @@ } }, "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-3.0.0.tgz", + "integrity": "sha512-zPMVc3ZYlGLNk4mpK1NzP2wg0ml9t7fUgDsayR5Y5rSzxQilzR9FGu/EH2jQOcKSAeAfWeylyW8juy3OkWRvNA==" }, "array-includes": { "version": "3.1.4", @@ -8458,21 +7919,11 @@ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, - "async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -8522,20 +7973,6 @@ "tweetnacl": "^0.14.3" } }, - "big-integer": { - "version": "1.6.48", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", - "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==" - }, - "binary": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", - "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", - "requires": { - "buffers": "~0.1.1", - "chainsaw": "~0.1.0" - } - }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -8543,20 +7980,20 @@ "dev": true }, "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "version": "2.0.0-beta.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.0.0-beta.1.tgz", + "integrity": "sha512-I1v2bt2OdYqtmk8nEFZuEf+9Opb30DphYwTPDbgg/OorSAoJOuTpWyDrZaSWQw7FdoevbBRCP2+9z/halXSWcA==", "requires": { - "bytes": "3.1.0", + "bytes": "3.1.1", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "~1.1.2", - "http-errors": "1.7.2", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "qs": "6.9.6", + "raw-body": "2.4.2", + "type-is": "~1.6.18" } }, "boxen": { @@ -8680,11 +8117,6 @@ } } }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" - }, "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -8695,16 +8127,6 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, - "buffer-indexof-polyfill": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", - "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==" - }, - "buffers": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", - "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=" - }, "busboy": { "version": "0.2.14", "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", @@ -8743,9 +8165,9 @@ "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=" }, "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", + "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==" }, "cacheable-lookup": { "version": "5.0.4", @@ -8803,14 +8225,6 @@ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, - "chainsaw": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", - "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", - "requires": { - "traverse": ">=0.3.0 <0.4" - } - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -8822,11 +8236,6 @@ "supports-color": "^5.3.0" } }, - "child_process": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz", - "integrity": "sha1-sffn/HPSXn/R1FWtyU4UODAYK1o=" - }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -8896,17 +8305,6 @@ "delayed-stream": "~1.0.0" } }, - "compress-commons": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.0.2.tgz", - "integrity": "sha512-qhd32a9xgzmpfoga1VQEiLEwdKZ6Plnpx5UCgIsf89FSolyJ7WnifY4Gtjgv5WR6hWAyRaHxC5MiEhU/38U70A==", - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^4.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" - } - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -8948,11 +8346,18 @@ } }, "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "5.2.1" + }, + "dependencies": { + "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==" + } } }, "content-type": { @@ -8961,9 +8366,9 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" }, "cookie-signature": { "version": "1.0.6", @@ -8984,24 +8389,6 @@ "vary": "^1" } }, - "crc-32": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", - "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", - "requires": { - "exit-on-epipe": "~1.0.1", - "printj": "~1.1.0" - } - }, - "crc32-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.1.tgz", - "integrity": "sha512-FN5V+weeO/8JaXsamelVYO1PHyeCsuL3HcG4cqsj0ceARcocxalaShCsohZMSAF+db7UYFwBy1rARK/0oFItUw==", - "requires": { - "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" - } - }, "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -9157,38 +8544,6 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "requires": { - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -9796,24 +9151,19 @@ } } }, - "exit-on-epipe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", - "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==" - }, "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "version": "5.0.0-beta.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.0.0-beta.1.tgz", + "integrity": "sha512-KPtBrlZoQu2Ps0Ce/Imqtq73AB0KBJ8Gx59yZQ3pmDJU2/LhcoZETo03oSgtTQufbcLXt/WBITk/jMjl/WMyrQ==", "requires": { "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", + "array-flatten": "3.0.0", + "body-parser": "2.0.0-beta.1", + "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.0", + "cookie": "0.4.1", "cookie-signature": "1.0.6", - "debug": "2.6.9", + "debug": "3.1.0", "depd": "~1.1.2", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -9822,20 +9172,37 @@ "fresh": "0.5.2", "merge-descriptors": "1.0.1", "methods": "~1.1.2", + "mime-types": "~2.1.34", "on-finished": "~2.3.0", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", + "path-is-absolute": "1.0.1", + "proxy-addr": "~2.0.7", + "qs": "6.9.6", "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", + "router": "2.0.0-beta.1", + "safe-buffer": "5.2.1", + "send": "1.0.0-beta.1", + "serve-static": "2.0.0-beta.1", + "setprototypeof": "1.2.0", "statuses": "~1.5.0", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "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==" + } } }, "express-jwt": { @@ -9856,38 +9223,6 @@ } } }, - "express-session": { - "version": "1.17.2", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", - "integrity": "sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ==", - "requires": { - "cookie": "0.4.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-headers": "~1.0.2", - "parseurl": "~1.3.3", - "safe-buffer": "5.2.1", - "uid-safe": "~2.1.5" - }, - "dependencies": { - "cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "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==" - } - } - }, "express-unless": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/express-unless/-/express-unless-0.3.1.tgz", @@ -9999,9 +9334,9 @@ "dev": true }, "follow-redirects": { - "version": "1.14.7", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", - "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==" + "version": "1.14.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", + "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==" }, "forever-agent": { "version": "0.6.1", @@ -10019,31 +9354,15 @@ } }, "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^1.0.0" - } - }, "fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -10052,11 +9371,6 @@ "minipass": "^3.0.0" } }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==" - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -10069,27 +9383,6 @@ "dev": true, "optional": true }, - "fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - } - } - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -10229,7 +9522,8 @@ "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true }, "growl": { "version": "1.10.5", @@ -10309,22 +9603,15 @@ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "requires": { "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - } + "toidentifier": "1.0.1" } }, "http2-wrapper": { @@ -10708,22 +9995,6 @@ "minimist": "^1.2.0" } }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - }, - "dependencies": { - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" - } - } - }, "jsonpath-plus": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-0.19.0.tgz", @@ -10805,38 +10076,6 @@ "package-json": "^6.3.0" } }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -10847,11 +10086,6 @@ "type-check": "~0.4.0" } }, - "listenercount": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", - "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=" - }, "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", @@ -10862,21 +10096,6 @@ "path-exists": "^3.0.0" } }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" - }, "lodash.foreach": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", @@ -10938,11 +10157,6 @@ "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", "dev": true }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" - }, "log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -11060,16 +10274,16 @@ } }, "mime-db": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", - "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==" + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" }, "mime-types": { - "version": "2.1.28", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", - "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "requires": { - "mime-db": "1.45.0" + "mime-db": "1.51.0" } }, "mimic-response": { @@ -11526,7 +10740,8 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "normalize-url": { "version": "4.5.1", @@ -11913,9 +11128,9 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.2.0.tgz", + "integrity": "sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==" }, "path-type": { "version": "4.0.0", @@ -11951,11 +11166,6 @@ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", "dev": true }, - "printj": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", - "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==" - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -11968,11 +11178,11 @@ "dev": true }, "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "requires": { - "forwarded": "~0.1.2", + "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, @@ -12011,9 +11221,9 @@ } }, "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==" }, "queue-microtask": { "version": "1.2.3", @@ -12026,11 +11236,6 @@ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" }, - "random-bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", - "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" - }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -12046,12 +11251,12 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", + "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", + "bytes": "3.1.1", + "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } @@ -12076,24 +11281,6 @@ } } }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdir-glob": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.1.tgz", - "integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==", - "requires": { - "minimatch": "^3.0.4" - } - }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -12262,6 +11449,19 @@ "glob": "^7.1.3" } }, + "router": { + "version": "2.0.0-beta.1", + "resolved": "https://registry.npmjs.org/router/-/router-2.0.0-beta.1.tgz", + "integrity": "sha512-GLoYgkhAGAiwVda5nt6Qd4+5RAPuQ4WIYLlZ+mxfYICI+22gnIB3eCfmhgV8+uJNPS1/39DOYi/vdrrz0/ouKA==", + "requires": { + "array-flatten": "3.0.0", + "methods": "~1.1.2", + "parseurl": "~1.3.3", + "path-to-regexp": "3.2.0", + "setprototypeof": "1.2.0", + "utils-merge": "1.0.1" + } + }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -12313,34 +11513,43 @@ } }, "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.0.0-beta.1.tgz", + "integrity": "sha512-OKTRokcl/oo34O8+6aUpj8Jf2Bjw2D0tZzmX0/RvyfVC9ZOZW+HPAWAlhS817IsRaCnzYX1z++h2kHFr2/KNRg==", "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", + "debug": "3.1.0", "destroy": "~1.0.4", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", + "http-errors": "1.8.1", + "mime-types": "~2.1.34", + "ms": "2.1.3", "on-finished": "~2.3.0", "range-parser": "~1.2.1", "statuses": "~1.5.0" }, "dependencies": { - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, @@ -12354,25 +11563,20 @@ } }, "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "version": "2.0.0-beta.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.0.0-beta.1.tgz", + "integrity": "sha512-DEJ9on/tQeFO2Omj7ovT02lCp1YgP4Kb8W2lv2o/4keTFAbgc8HtH3yPd47++2wv9lvQeqiA7FHFDe5+8c4XpA==", "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.1" + "send": "1.0.0-beta.1" } }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "shebang-command": { "version": "2.0.0", @@ -12518,21 +11722,6 @@ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "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==" - } - } - }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -12652,39 +11841,6 @@ } } }, - "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "requires": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } - } - }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -12723,9 +11879,9 @@ } }, "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, "touch": { "version": "3.1.0", @@ -12744,11 +11900,6 @@ "punycode": "^2.1.1" } }, - "traverse": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", - "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" - }, "ts-node": { "version": "10.2.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", @@ -12859,14 +12010,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==" }, - "uid-safe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", - "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", - "requires": { - "random-bytes": "~1.0.0" - } - }, "unbox-primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", @@ -12893,62 +12036,11 @@ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" }, - "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==" - }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, - "unzipper": { - "version": "0.10.11", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", - "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", - "requires": { - "big-integer": "^1.6.17", - "binary": "~0.3.0", - "bluebird": "~3.4.1", - "buffer-indexof-polyfill": "~1.0.0", - "duplexer2": "~0.1.4", - "fstream": "^1.0.12", - "graceful-fs": "^4.2.2", - "listenercount": "~1.0.1", - "readable-stream": "~2.3.6", - "setimmediate": "~1.0.4" - }, - "dependencies": { - "bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "update-notifier": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", @@ -13272,16 +12364,6 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true - }, - "zip-stream": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.0.4.tgz", - "integrity": "sha512-a65wQ3h5gcQ/nQGWV1mSZCEzCML6EK/vyVPcrPNynySP1j3VBbQKh3nhC8CbORb+jfl2vXvh56Ul5odP1bAHqw==", - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^4.0.2", - "readable-stream": "^3.6.0" - } } } } diff --git a/BackEnd/package.json b/BackEnd/package.json index dd4fe05..4d84875 100644 --- a/BackEnd/package.json +++ b/BackEnd/package.json @@ -22,17 +22,13 @@ "license": "MIT", "dependencies": { "@kubernetes/client-node": "^0.13.2", - "archiver": "^5.2.0", + "adm-zip": "^0.5.9", "axios": "^0.24.0", - "child_process": "^1.0.2", "cors": "2.8.5", "dotenv": "^10.0.0", "envalid": "^7.1.1", - "express": "^4.17.1", + "express": "^5.0.0-beta.1", "express-jwt": "6.0.0", - "express-session": "^1.17.2", - "fs-extra": "^9.0.1", - "fs-readdir-recursive": "^1.1.0", "helmet": "^4.3.1", "jsonwebtoken": "8.5.1", "mongoose": "^6.1.4", @@ -41,18 +37,18 @@ "multer": "^1.4.2", "passport": "0.4.1", "passport-local": "1.0.0", - "rimraf": "^3.0.2", "slug": "4.0.2", - "typescript": "^4.5.4", - "unzipper": "^0.10.11" + "typescript": "^4.5.4" }, "devDependencies": { + "@types/adm-zip": "^0.4.34", "@types/cors": "^2.8.12", "@types/express": "^4.17.13", - "@types/express-session": "^1.17.4", "@types/mocha": "^9.0.0", "@types/morgan": "^1.9.3", + "@types/multer": "^1.4.7", "@types/node": "^17.0.5", + "@types/passport": "^1.0.7", "@typescript-eslint/eslint-plugin": "^5.9.0", "@typescript-eslint/parser": "^5.9.0", "eslint": "^7.12.1", diff --git a/BackEnd/src/app.ts b/BackEnd/src/app.ts index d0c4d83..2e20ba3 100644 --- a/BackEnd/src/app.ts +++ b/BackEnd/src/app.ts @@ -2,9 +2,10 @@ import express from 'express' import { AddressInfo } from 'net' import env from './env' -import { middlesDev, middlesProd } from './middlewares' +import { errorsDev, errorsProd, middlesDev, middlesProd } from './middlewares' import { api } from './controllers' import { SwiftService } from './cloud/SwiftService' +import { AdmZipService } from './archive/AdmZipService' const mongoose = require('mongoose') @@ -31,7 +32,16 @@ require('./configs/passport'); const cloud = new SwiftService() cloud.init() -app.use('/api', api(cloud)) +app.use('/api', api(cloud, new AdmZipService())) + +let errhandlers: Function[] = [] +if (env.isDev) { + errhandlers = Object.values(errorsDev) +} else if (env.isProd) { + errhandlers = Object.values(errorsProd) +} +errhandlers.forEach(eh => app.use(eh())) + // finally, let's start our server... const server = app.listen(process.env.PORT || 3000, function () { diff --git a/BackEnd/src/archive/AdmZipService.spec.ts b/BackEnd/src/archive/AdmZipService.spec.ts new file mode 100644 index 0000000..c185c7b --- /dev/null +++ b/BackEnd/src/archive/AdmZipService.spec.ts @@ -0,0 +1,61 @@ +import { strict as assert } from 'assert' +import path from 'path' + +import { ArchiveService, fileData, PathFileData } from './ArchiveService' +import { AdmZipService } from './AdmZipService' +import { DataKind, inPathData, outBufferData } from 'utils/Data' + +const assets = './assets' + +describe('AdmZipService', function () { + const service: ArchiveService = new AdmZipService() + const archivePath = path.join(assets, 'archive.zip') + const archiveDir = 'archiveDir/' + const archiveFile = path.join(archiveDir, 'archiveFile') + const archiveData = 'archiveData' + + describe(`unzip(${archivePath})`, function () { + it('should unzip archive', async function () { + const files = await service.unzip(inPathData(archivePath), outBufferData) + assert.equal(files.length, 1) + + const file = files[0] + assert.equal(file.kind, DataKind.Buffer) + assert.equal(file.zipPath, archiveFile) + assert.equal(file.input.toString(), archiveData) + }) + }) + + describe(`zip(${archiveFile})`, function () { + it('should zip archive file', async function () { + const archiveFilePath = path.join(assets, archiveFile) + const archiveFileData = + fileData(inPathData(archiveFilePath), archiveFile) as PathFileData + const archive = await service.zip([archiveFileData], outBufferData) + + const files = await service.unzip(archive, outBufferData) + assert.equal(files.length, 1) + + const file = files[0] + assert.equal(file.kind, DataKind.Buffer) + assert.equal(file.zipPath, archiveFile) + assert.equal(file.input.toString(), archiveData) + }) + }) + + describe(`zipFromDir(${archiveDir})`, function () { + it('should zip from directory', async function () { + const archiveDirPath = path.join(assets, archiveDir) + const archiveFileData = + fileData(inPathData(archiveDirPath), archiveDir) as PathFileData + const archive = await service.zipFromDir(archiveFileData, outBufferData) + + const files = await service.unzip(archive, outBufferData) + + const file = files[0] + assert.equal(file.kind, DataKind.Buffer) + assert.equal(file.zipPath, archiveFile) + assert.equal(file.input.toString(), archiveData) + }) + }) +}) diff --git a/BackEnd/src/archive/AdmZipService.ts b/BackEnd/src/archive/AdmZipService.ts new file mode 100644 index 0000000..f5ebc38 --- /dev/null +++ b/BackEnd/src/archive/AdmZipService.ts @@ -0,0 +1,72 @@ +import path from 'path' +import AdmZip from 'adm-zip' + +import { + DataKind, + inBufferData, + inPathData, + OutputData as DataOptions +} from 'utils/Data' +import { + ArchiveData, + ArchiveService, + fileData, + FileData, + PathFileData +} from './ArchiveService' + +export class AdmZipService implements ArchiveService { + /** + * for loop is indexed to preserve order in iteration + */ + unzip (archive: ArchiveData, options: DataOptions): Promise { + const zip = new AdmZip(archive.input) + + const files = zip.getEntries().filter(file => !file.isDirectory) + switch (options.kind) { + case DataKind.Buffer: + return Promise.all(files.map(async file => + fileData(inBufferData(file.getData()), file.entryName))) + case DataKind.Path: + zip.extractAllTo(options.output) + return Promise.all(files.map(async file => { + const filePath = path.join(options.output, file.entryName) + return fileData(inPathData(filePath), file.entryName) + })) + } + } + + async zip (files: FileData[], options: DataOptions): Promise { + const zip = new AdmZip() + + await Promise.all(files.map(async file => { + switch (file.kind) { + case DataKind.Buffer: + return zip.addFile(file.zipPath, file.input) + case DataKind.Path: + return zip.addLocalFile(file.input, undefined, file.zipPath) + } + })) + switch (options.kind) { + case DataKind.Buffer: + return inBufferData(zip.toBuffer()) + case DataKind.Path: + zip.writeZip(options.output) + return inPathData(options.output) + } + } + + async zipFromDir (dir: PathFileData, + options: DataOptions): Promise { + const zip = new AdmZip() + + zip.addLocalFolder(dir.input, dir.zipPath) + switch (options.kind) { + case DataKind.Buffer: + return inBufferData(zip.toBuffer()) + case DataKind.Path: + zip.writeZip(options.output) + return inPathData(options.output) + } + } +} diff --git a/BackEnd/src/archive/ArchiveService.ts b/BackEnd/src/archive/ArchiveService.ts new file mode 100644 index 0000000..2f6857a --- /dev/null +++ b/BackEnd/src/archive/ArchiveService.ts @@ -0,0 +1,47 @@ +import { + BufferInputData, + convertData, + InputData, + OutputData as DataOptions, + PathInputData +} from 'utils/Data' + +export type ArchiveData = InputData + +export type ZipPath = { zipPath: string } + +export type BufferFileData = BufferInputData & ZipPath +export type PathFileData = PathInputData & ZipPath + +export type FileData = BufferFileData | PathFileData + +export interface ArchiveService { + /** + * Unzip archive into a list of Buffer or a list of local paths + * a DataKind.Path options output is a directory + */ + unzip(archive: ArchiveData, + options: DataOptions): Promise + + /** + * Zip files into an archive + * an archive can be a Buffer or a local path + * a DataKind.Path options is the path to the archive + */ + zip(files: FileData[], options: DataOptions): Promise + + // TODO: implements in parent class + /** + * + */ + zipFromDir(dir: PathFileData, options: DataOptions): Promise +} + +export function fileData (data: InputData, zipPath: string) : FileData { + return { ...data, zipPath } +} + +export function convertFileData (file: FileData, options: DataOptions) +: FileData { + return { ...convertData(file, options), zipPath: file.zipPath } +} diff --git a/BackEnd/src/controllers/index.ts b/BackEnd/src/controllers/index.ts index 4b2ae36..7cd5573 100644 --- a/BackEnd/src/controllers/index.ts +++ b/BackEnd/src/controllers/index.ts @@ -1,31 +1,24 @@ -import { Router, Request, Response, NextFunction } from 'express' +import { + Router, + Request, + Response, + NextFunction, + RequestHandler +} from 'express' import { CloudService } from 'cloud/CloudService' +import { ArchiveService } from 'archive/ArchiveService' import { userAPI } from './users' import { serverAPI } from './server' import { uploadAPI } from './upload' -export function api (cloud: CloudService) { +export function api (cloud: CloudService, archive: ArchiveService) { const router = Router() /* TODO: use ES6 import */ router.use(userAPI(cloud)) router.use('/profiles', require('./profiles')) // eslint-disable-line router.use('/servers', serverAPI(cloud)) - router.use('/uploads', uploadAPI(cloud)) - - /* TODO: move or remove this error handler */ - function mongooseErrorHandler (err: any, _req: Request, - res: Response, next: NextFunction) { - if (err.name === 'ValidationError') { - const errors: {[key: string]: any} = err.errors - Object.keys(errors).forEach((key: string) => { - errors[key] = errors[key].message - }) - return res.status(422).json({ errors }) - } - return next(err) - } - router.use(mongooseErrorHandler) + router.use('/uploads', uploadAPI(cloud, archive)) return router } diff --git a/BackEnd/src/controllers/profiles.ts b/BackEnd/src/controllers/profiles.ts index 0c9956f..6e05236 100644 --- a/BackEnd/src/controllers/profiles.ts +++ b/BackEnd/src/controllers/profiles.ts @@ -1,46 +1,43 @@ -import { Router } from 'express'; -var mongoose = require('mongoose'); -var User = mongoose.model('User'); +import { Router } from 'express' -import auth from './auth'; +import auth from './auth' -import api_code from '../configs/api_code'; +import apiCode from '../configs/api_code' -const router = Router(); +// eslint-disable-next-line +const mongoose = require('mongoose') +const User = mongoose.model('User') + +const router = Router() // Preload user profile on routes with ':username' -router.param('username', function (req : any, res, next, username) { - User.findOne({ username: username }).then(function (user : any) { - if (!user) { return res.sendStatus(api_code.not_found).json({ errors: { errors: 'User not found' } }); } - - req.profile = user; - - return next(); - }).catch(next); -}); - -router.get('/:username', auth.required, function (req : any, res, next) { - Promise.all([ - req.payload ? User.findById(req.payload.id) : null, - ]).then(function (results) { - var user = results[0]; - if (!user - || (!user.isAdmin() && !user.authorized) - || ((user.username !== req.profile.username) && (!user.isAdmin())) - ) { return res.sendStatus(api_code.forbidden); } - else return res.json({ profile: req.profile.toProfileJSONFor(user) }); - }).catch(next); -}); +router.param('username', async function (req: any, res, next, username) { + const user = await User.findOne({ username: username }) + if (!user) { + return res.sendStatus(apiCode.not_found) + .json({ errors: { errors: 'User not found' } }) + } + req.profile = user + return next() +}) + +router.get('/:username', auth.required, async function (req: any, res) { + const user = await User.findById(req.payload.id) + if (!user || (!user.isAdmin() && !user.authorized) || + ((user.username !== req.profile.username) && (!user.isAdmin()))) { + return res.sendStatus(apiCode.forbidden) + } + return res.json({ profile: req.profile.toProfileJSONFor(user) }) +}) // code duplication to remove in the future -router.get('/user/:username', auth.required, function (req : any, res, next) { - User.findById(req.payload.id).then(function (user : any) { - if (!user - || (!user.isAdmin() && !user.authorized) - || ((user.username !== req.profile.username) && (!user.isAdmin())) - ) { return res.sendStatus(api_code.forbidden); } - else return res.json({ user: req.profile.toAuthJSON() }); - }).catch(next); -}); - -module.exports = router; +router.get('/user/:username', auth.required, async function (req: any, res) { + const user = await User.findById(req.payload.id) + if (!user || (!user.isAdmin() && !user.authorized) || + ((user.username !== req.profile.username) && (!user.isAdmin()))) { + return res.sendStatus(apiCode.forbidden) + } + return res.json({ user: req.profile.toAuthJSON() }) +}) + +module.exports = router diff --git a/BackEnd/src/controllers/server.ts b/BackEnd/src/controllers/server.ts index 02089e5..421c5fd 100644 --- a/BackEnd/src/controllers/server.ts +++ b/BackEnd/src/controllers/server.ts @@ -1,385 +1,369 @@ -import { Router } from 'express'; +import { Router } from 'express' +import fs from 'fs' import path from 'path' -import auth from './auth'; +import auth from './auth' -import * as server_functions from '../lib/server_functions'; -import * as upload_functions from '../lib/upload_functions'; -import * as log_functions from '../lib/log_functions'; +// eslint-disable-next-line +import * as server_functions from '../lib/server_functions' +// eslint-disable-next-line +import * as log_functions from '../lib/log_functions' -import api_code from '../configs/api_code'; -import log_message from '../configs/log_message'; +import apiCode from '../configs/api_code' + +// eslint-disable-next-line +import log_message from '../configs/log_message' import env from 'env' import { Server, User } from 'models' -import { CloudService } from 'cloud/CloudService'; +import { CloudService } from 'cloud/CloudService' -export function serverAPI(cloud: CloudService) { - const router = Router(); +export function serverAPI (cloud: CloudService) { + const router = Router() // Preload server objects on routes with ':server' - router.param('server', function(req: any, res, next, slug) { - Server.findOne({ slug: slug }) - .populate('author') - .then(function(server: any) { - if (!server) { return res.sendStatus(api_code.not_found).json({ errors: { errors: 'Server ' + slug + ' not found' } }); } - - req.server = server; - - return next(); - }).catch(next); - }); - - router.get('/', auth.required, function(req: any, res, next) { - - User.findById(req.payload.id).then(function(user: any) { - if (!user) { - log_functions.create('error', 'get /server/', - log_message.user_account_unknown + user, - user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - if (!user.isAdmin() && !user.authorized) { - log_functions.create('error', 'get /server/', - log_message.user_activated_error, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - - if ((user.username !== req.query.author) && !user.isAdmin()) { - log_functions.create('error', 'get /server/', - log_message.user_owner_error, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - var author = req.query.author; - user.findAnUser(author).then(function(results: any) { - - author = results[0]; - console.log(author); - user.findAllServersOfAnUser(req.query, author, req.payload) - .then(function(results: any) { - var servers = results[0]; - var serversCount = results[1]; - log_functions.create('general', 'get /server/', 'ok', user, req.server) - return res.json({ - servers: servers.map(function(server: any) { - return server.toJSONFor(author); - }), - serversCount: serversCount - }); - }); - }).catch(next); - }).catch(next); - - }); - - router.post('/', auth.required, function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (!user) { - log_functions.create('error', 'post /server/', - log_message.user_account_unknown + user, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - if (!user.active) { - log_functions.create('error', 'post /server/', - log_message.user_account_error, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - if (!user.isAdmin() && !user.authorized) { - log_functions.create('error', 'post /server/', - log_message.user_activated_error, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - var server = new Server(req.body.server); - server.author = user; - log_functions.create('bin', 'post /server/', log_message.user_server_created, user, server); - return server.save().then(async function() { - await cloud.createContainer(server.slug) - await cloud.copyObjects(env.OS_DEFAULT_CONTAINER, server.slug) - - log_functions.create('general', 'post /server/', - log_message.user_swift_created, user, server); - console.log('swift created'); - return res.json({ server: server.toJSONFor(user) }); - }).catch((err: any) => { - console.error(err) - log_functions.create('error', 'post /server/', - log_message.user_swift_error, user, server); - return res.status(api_code.error).send({ errors: { err } }); - }) - }).catch(next); - }); + router.param('server', async function (req: any, res, next, slug) { + const server = await Server.findOne({ slug: slug }).populate('author') + if (!server) { + return res.sendStatus(apiCode.not_found) + .json({ errors: { errors: 'Server ' + slug + ' not found' } }) + } + req.server = server + return next() + }) + + router.get('/', auth.required, async function (req: any, res) { + const user = await User.findById(req.payload.id) + if (!user) { + log_functions.create('error', 'get /server/', + log_message.user_account_unknown + user, + user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.isAdmin() && !user.authorized) { + log_functions.create('error', 'get /server/', + log_message.user_activated_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + + if ((user.username !== req.query.author) && !user.isAdmin()) { + log_functions.create('error', 'get /server/', + log_message.user_owner_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + + const [author] = await user.findAnUser(req.query.author) + console.log(author) + const [servers, serversCount] = + await user.findAllServersOfAnUser(req.query, author, req.payload) + log_functions.create('general', 'get /server/', 'ok', user, req.server) + return res.json({ + servers: servers.map((server: any) => server.toJSONFor(author)), + serversCount: serversCount + }) + }) + + router.post('/', auth.required, async function (req: any, res, _next) { + const user = await User.findById(req.payload.id) + if (!user) { + log_functions.create('error', 'post /server/', + log_message.user_account_unknown + user, user, + req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.active) { + log_functions.create('error', 'post /server/', + log_message.user_account_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.isAdmin() && !user.authorized) { + log_functions.create('error', 'post /server/', + log_message.user_activated_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + + const server = new Server(req.body.server) + server.author = user + log_functions.create('bin', 'post /server/', + log_message.user_server_created, user, server) + await server.save() + await cloud.createContainer(server.slug) + await cloud.copyObjects(env.OS_DEFAULT_CONTAINER, server.slug) + + log_functions.create('general', 'post /server/', + log_message.user_swift_created, user, server) + console.log('swift created') + return res.json({ server: server.toJSONFor(user) }) + }) // return a server - router.get('/:server', auth.required, function(req: any, res, next) { - Promise.all([ - req.payload ? User.findById(req.payload.id) : null, - req.server.populate('author'), - - ]).then(function(results) { - var user = results[0]; - var server = req.server.toJSONFor(user); - if (!user) { - log_functions.create('error', 'get /server/:' + req.server.slug, - log_message.user_account_unknown + user, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - if (!user.isAdmin() && !user.authorized) { - log_functions.create('error', 'get /server/:' + req.server.slug, - log_message.user_activated_error, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - - if ((user.username !== server.author.username) && (!user.isAdmin())) { - log_functions.create('error', 'get /server/:' + req.server.slug, - log_message.user_account_error, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - log_functions.create('general', 'get /server/:' + req.server.slug, 'ok', user, req.server); - return res.json({ server }); - - }).catch(next); - }); + router.get('/:server', auth.required, async function (req: any, res) { + const user = await User.findById(req.payload.id) + if (!user) { + log_functions.create('error', 'get /server/:' + req.server.slug, + log_message.user_account_unknown + user, + user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.isAdmin() && !user.authorized) { + log_functions.create('error', 'get /server/:' + req.server.slug, + log_message.user_activated_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + + const server = req.server.toJSONFor(user) + if ((user.username !== server.author.username) && (!user.isAdmin())) { + log_functions.create('error', 'get /server/:' + req.server.slug, + log_message.user_account_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + + log_functions.create('general', 'get /server/:' + req.server.slug, 'ok', + user, req.server) + return res.json({ server }) + }) // update server - router.put('/:server', auth.required, function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (!user.active) { - log_functions.create('error', 'put /server/:' + req.server.slug, - log_message.user_account_error, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - if (!user.isAdmin() && !user.authorized) { - log_functions.create('error', 'put /server/:' + req.server.slug, - log_message.user_activated_error, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - if (user.processing) { - log_functions.create('error', 'put /server/:' + req.server.slug, - log_message.user_processing_unauthorised, user, req.server); - return res.sendStatus(api_code.forbidden); - } - if (req.server.author._id.toString() === req.payload.id.toString() || user.isAdmin()) { - - if (typeof req.body.server.title !== 'undefined') { - req.server.title = req.body.server.title; - } - - if (typeof req.body.server.description !== 'undefined') { - req.server.description = req.body.server.description; - } - - if (typeof req.body.server.body !== 'undefined') { - req.server.body = req.body.server.body; - } - - req.server.save().then(function(server: any) { - log_functions.create('bin', 'put /server/:' + req.server.slug, 'server information updated', user, req.server); - return res.json({ server: server.toJSONFor(user) }); - }).catch(next); - } else { - log_functions.create('error', 'put /server/:' + req.server.slug, - log_message.user_owner_error, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - }); - }); - - //disable or enable a server - router.post('/disable/:server', auth.required, function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (req.server.author._id.toString() === req.payload.id.toString() || user.isAdmin()) { - if (!user.active) { - log_functions.create('error', 'post /server/disable/:' + req.server.slug, - log_message.user_account_error, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - if (!user.isAdmin() && !user.authorized) { - log_functions.create('error', 'post /server/disable/:' + req.server.slug, - log_message.user_activated_error, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - if (user.processing) { - log_functions.create('error', 'post /server/disable/:' + req.server.slug, - log_message.user_processing_unauthorised, user, req.server); - return res.sendStatus(api_code.forbidden); - } - - var slug = req.server.slug; - var username = req.server.author.username; - var namespace = 'default'; - - if (req.server.active) { - console.log('shut_off'); - var volume = req.server.volume; - console.log('volume : ' + volume); - user.startProcessing().then(() => { - log_functions.create('bin', 'post /server/disable/:' + req.server.slug, log_message.user_processing_start, user); - console.log('user.processing : ' + user.processing); - server_functions.removekubelink(slug, namespace) - .then((response: any) => { - user.endProcessing().then(() => { - log_functions.create('bin', 'post /server/disable/:' + req.server.slug, log_message.user_processing_end, user); - console.log('user.processing : ' + user.processing); - req.server.active = false; - req.server.save().then(function() { - log_functions.create('bin', 'post /server/disable/:' + req.server.slug, log_message.server_shut_off, user, req.server); - return res.sendStatus(api_code.ok); - }); - }); - }, (err: any) => { - user.endProcessing().then(() => { - log_functions.create('bin', 'post /server/disable/:' + req.server.slug, log_message.server_shut_off, user); - return res.status(api_code.error).send({ errors: { err } }); - }); - }); - }); - } else { - console.log('shut_on'); - user.startProcessing().then(() => { - log_functions.create('bin', 'post /server/disable/:' + req.server.slug, log_message.user_processing_start, user); - console.log('user.processing : ' + user.processing); - server_functions.createkubelink(slug, username, namespace) - .then((response: any) => { - user.endProcessing().then(() => { - log_functions.create('bin', 'post /server/disable/:' + req.server.slug, log_message.user_processing_end, user); - console.log('user.processing : ' + user.processing); - req.server.volume = response; - req.server.active = true; - req.server.save().then(function() { - log_functions.create('bin', 'post /server/disable/:' + req.server.slug, log_message.server_shut_on, user, req.server); - return res.sendStatus(api_code.ok); - }); - }); - }, (err: any) => { - user.endProcessing().then(() => { - log_functions.create('bin', 'post /server/disable/:' + req.server.slug, log_message.user_processing_end, user); - return res.status(api_code.error).send({ errors: { err } }); - }); - }); - }); - } - } else { - log_functions.create('error', 'get /server/disable/:' + req.server.slug, - log_message.user_owner_error, user, req.server); - return res.sendStatus(api_code.forbidden); - } - }).catch(next); - }); + router.put('/:server', auth.required, async function (req: any, res) { + const user = await User.findById(req.payload.id) + if (!user.active) { + log_functions.create('error', 'put /server/:' + req.server.slug, + log_message.user_account_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.isAdmin() && !user.authorized) { + log_functions.create('error', 'put /server/:' + req.server.slug, + log_message.user_activated_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (user.processing) { + log_functions.create('error', 'put /server/:' + req.server.slug, + log_message.user_processing_unauthorised, + user, req.server) + return res.sendStatus(apiCode.forbidden) + } + if (req.server.author._id.toString() !== req.payload.id.toString() && + !user.isAdmin()) { + log_functions.create('error', 'put /server/:' + req.server.slug, + log_message.user_owner_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + } + + if (typeof req.body.server.title !== 'undefined') { + req.server.title = req.body.server.title + } + if (typeof req.body.server.description !== 'undefined') { + req.server.description = req.body.server.description + } + if (typeof req.body.server.body !== 'undefined') { + req.server.body = req.body.server.body + } + + const server = req.server.save() + log_functions.create('bin', 'put /server/:' + req.server.slug, + 'server information updated', user, req.server) + return res.json({ server: server.toJSONFor(user) }) + }) + + // disable or enable a server + router.post('/disable/:server', auth.required, async function (req: any, res: any) { + const user = await User.findById(req.payload.id) + if (req.server.author._id.toString() !== req.payload.id.toString() && + user.isAdmin()) { + log_functions.create('error', 'get /server/disable/:' + req.server.slug, + log_message.user_owner_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + } + if (!user.active) { + log_functions.create('error', 'post /server/disable/:' + req.server.slug, + log_message.user_account_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.isAdmin() && !user.authorized) { + log_functions.create('error', 'post /server/disable/:' + req.server.slug, + log_message.user_activated_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (user.processing) { + log_functions.create('error', 'post /server/disable/:' + req.server.slug, + log_message.user_processing_unauthorised, + user, req.server) + return res.sendStatus(apiCode.forbidden) + } + + const slug = req.server.slug + const username = req.server.author.username + const namespace = 'default' + + if (!req.server.active) { + console.log('shut_on') + await user.startProcessing() + console.log('user.processing : ' + user.processing) + log_functions.create('bin', 'post /server/disable/:' + req.server.slug, + log_message.user_processing_start, user) + + await server_functions.createkubelink(slug, username, namespace) + + await user.endProcessing() + console.log('user.processing : ' + user.processing) + log_functions.create('bin', 'post /server/disable/:' + req.server.slug, + log_message.user_processing_end, user) + + req.server.active = true + await req.server.save() + log_functions.create('bin', 'post /server/disable/:' + req.server.slug, + log_message.server_shut_on, user, req.server) + return res.sendStatus(apiCode.ok) + } else { + console.log('shut_off') + await user.startProcessing() + console.log('user.processing : ' + user.processing) + log_functions.create('bin', 'post /server/disable/:' + req.server.slug, + log_message.user_processing_start, user) + + server_functions.removekubelink(slug, namespace) + + await user.endProcessing() + log_functions.create('bin', 'post /server/disable/:' + req.server.slug, + log_message.user_processing_end, user) + console.log('user.processing : ' + user.processing) + + req.server.active = false + await req.server.save() + log_functions.create('bin', 'post /server/disable/:' + req.server.slug, + log_message.server_shut_off, user, req.server) + return res.sendStatus(apiCode.ok) + } + }) // delete server - router.delete('/:server', auth.required, function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (!user) { - log_functions.create('error', 'delete /server/:' + req.server.slug, - log_message.user_account_unknown + user, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - if (!user.active) { - log_functions.create('error', 'delete /server/:' + req.server.slug, - log_message.user_account_error, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - if (!user.isAdmin() && !user.authorized) { - log_functions.create('error', 'delete /server/:' + req.server.slug, - log_message.user_activated_error, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - if (user.processing) { - log_functions.create('error', 'delete /server/:' + req.server.slug, - log_message.user_processing_unauthorised, user, req.server); - return res.sendStatus(api_code.forbidden); - } - - if (req.server.author._id.toString() === req.payload.id.toString() || user.isAdmin()) { - - var slug = req.server.slug; - var namespace = 'default'; - console.log('asking for a deletion'); - console.log('slug : ' + slug); - log_functions.create('bin', 'delete /server/:' + req.server.slug, log_message.user_deletion_ask, user, req.server); - - user.startProcessing().then(async () => { - log_functions.create('bin', 'delete /server/:' + req.server.slug, log_message.user_processing_start, user); - - await server_functions.removekubelink(slug, namespace) - console.log('kubelink removed') - - await cloud.deleteObjects(slug) - await cloud.deleteContainer(slug) - console.log('swift container removed') - - const serverDir = path.join('./uploads', user.username, slug) - await upload_functions.removeDir(serverDir) - console.log('server deleted') - - await user.endProcessing() - log_functions.create('bin', 'delete /server/:' + req.server.slug, log_message.user_processing_end, user); - await log_functions.create('bin', 'delete /server/:' + req.server.slug, log_message.server_deletion_ok, user, req.server) - await req.server.remove() - return res.sendStatus(api_code.ok) - }, async (err: any) => { - await user.endProcessing() - console.error(err); - log_functions.create('bin', 'delete /server/:' + req.server.slug, log_message.user_processing_end, user); - return res.status(api_code.error).send({ errors: { err } }); - }) - } else { - log_functions.create('error', 'delete /server/:' + req.server.slug, - log_message.user_owner_error, user, req.server); - return res.sendStatus(api_code.forbidden); - } - }).catch(next); - }); - - router.post('/token/:server', auth.required, function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (!user) { - log_functions.create('error', 'post /server/:' + req.server.slug, - log_message.user_account_unknown + user, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - if (!user.active) { - log_functions.create('error', 'post /server/:' + req.server.slug, - log_message.user_account_error, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - if (!user.isAdmin() && !user.authorized) { - log_functions.create('error', 'post /server/:' + req.server.slug, - log_message.user_activated_error, user, req.server); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - - if (req.server.author._id.toString() === req.payload.id.toString() || user.isAdmin()) { - - if (req.server.token !== undefined) { - console.log(req.server.token); - return res.status(api_code.error).send({ errors: 'teacher token already retrieve' }); - } else { - var slug = req.server.slug; - var namespace = 'default'; - user.startProcessing().then(() => server_functions.catchTeacherToken(slug, namespace)) - .then((token: any) => { - log_functions.create('bin', 'post /server/token:' + req.server.slug, log_message.user_token_ok, user, req.server); - req.server.token = token; - return req.server.save(); - }) - .then(() => user.endProcessing()) - .then(() => res.json({ server: req.server.toJSONFor(user) })) - .catch(async (err: any) => { - await user.endProcessing(); - log_functions.create('error', 'post /server/', - log_message.user_token_error + req.server.slug, - user, req.server); - return res.status(api_code.error).send({ errors: { err } }); - }); - } - } else { - log_functions.create('error', 'get /server/disable/:' + req.server.slug, - log_message.user_owner_error, user, req.server); - return res.sendStatus(api_code.forbidden); - } - }).catch(next); - }); + router.delete('/:server', auth.required, async function (req: any, res) { + const user = await User.findById(req.payload.id) + if (!user) { + log_functions.create('error', 'delete /server/:' + req.server.slug, + log_message.user_account_unknown + user, + user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.active) { + log_functions.create('error', 'delete /server/:' + req.server.slug, + log_message.user_account_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.isAdmin() && !user.authorized) { + log_functions.create('error', 'delete /server/:' + req.server.slug, + log_message.user_activated_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (user.processing) { + log_functions.create('error', 'delete /server/:' + req.server.slug, + log_message.user_processing_unauthorised, + user, req.server) + return res.sendStatus(apiCode.forbidden) + } + + if (req.server.author._id.toString() !== req.payload.id.toString() && + user.isAdmin()) { + log_functions.create('error', 'delete /server/:' + req.server.slug, + log_message.user_owner_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + } + + const slug = req.server.slug + const namespace = 'default' + + console.log('asking for a deletion') + console.log('slug : ' + slug) + log_functions.create('bin', 'delete /server/:' + req.server.slug, + log_message.user_deletion_ask, user, req.server) + + await user.startProcessing() + log_functions.create('bin', 'delete /server/:' + req.server.slug, + log_message.user_processing_start, user) + + await server_functions.removekubelink(slug, namespace) + console.log('kubelink removed') + + await cloud.deleteObjects(slug) + await cloud.deleteContainer(slug) + console.log('swift container removed') + + const serverDir = path.join('./uploads', user.username, slug) + await fs.promises.rm(serverDir, { recursive: true }) + console.log('server deleted') + + await user.endProcessing() + log_functions.create('bin', 'delete /server/:' + req.server.slug, + log_message.user_processing_end, user) + log_functions.create('bin', 'delete /server/:' + req.server.slug, + log_message.server_deletion_ok, user, req.server) + await req.server.remove() + return res.sendStatus(apiCode.ok) + }) + + router.post('/token/:server', auth.required, async function (req: any, res) { + const user = await User.findById(req.payload.id) + if (!user) { + log_functions.create('error', 'post /server/:' + req.server.slug, + log_message.user_account_unknown + user, + user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.active) { + log_functions.create('error', 'post /server/:' + req.server.slug, + log_message.user_account_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.isAdmin() && !user.authorized) { + log_functions.create('error', 'post /server/:' + req.server.slug, + log_message.user_activated_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (req.server.author._id.toString() !== req.payload.id.toString() && + user.isAdmin()) { + log_functions.create('error', 'get /server/disable/:' + req.server.slug, + log_message.user_owner_error, user, req.server) + return res.sendStatus(apiCode.forbidden) + } + + if (req.server.token !== undefined) { + console.log(req.server.token) + return res.status(apiCode.error) + .send({ errors: 'teacher token already retrieve' }) + } + + const slug = req.server.slug + const namespace = 'default' + await user.startProcessing() + + const token = server_functions.catchTeacherToken(slug, namespace) + log_functions.create('bin', 'post /server/token:' + req.server.slug, + log_message.user_token_ok, user, req.server) + req.server.token = token + + await req.server.save() + await user.endProcessing() + return res.json({ server: req.server.toJSONFor(user) }) + }) return router } diff --git a/BackEnd/src/controllers/upload.ts b/BackEnd/src/controllers/upload.ts index 7ca4be6..ace6e1b 100644 --- a/BackEnd/src/controllers/upload.ts +++ b/BackEnd/src/controllers/upload.ts @@ -1,497 +1,387 @@ -import { Router } from 'express'; +import axios from 'axios' +import { Router } from 'express' +import fs from 'fs' import path from 'path' +import { URL } from 'url' + +import auth from './auth' + +import apiCode from '../configs/api_code' +import { CloudService } from 'cloud/CloudService' +import { + ArchiveService, + PathFileData, + convertFileData, + fileData, + BufferFileData +} from 'archive/ArchiveService' +import { + inBufferData, + inPathData, + outBufferData, + outPathData +} from 'utils/Data' + +import multer from 'multer' +// eslint-disable-next-line +const mongoose = require('mongoose') + +let destPath = '' + +const User = mongoose.model('User') +const Server = mongoose.model('Server') + +const storage = multer.diskStorage({ + destination: (req: any, file: any, cb: any) => { + cb(null, 'uploads') + }, + filename: (req: any, file: any, cb: any) => { + destPath = `${req.payload.username}${path.extname(file.originalname)}` + req.archivePath = path.join('uploads', destPath) + cb(null, destPath) + } +}) +const upload = multer({ storage: storage }) + +export function uploadAPI (cloud: CloudService, archive: ArchiveService) { + const router = Router() -const mongoose = require('mongoose'); -const multer = require('multer'); + // Preload server objects on routes with ':server' + router.param('server', async (req, res, next, slug) => { + const server = await Server.findOne({ slug: slug }).populate('author') + if (!server) { + return res.sendStatus(apiCode.not_found) + .json({ errors: { errors: `Server ${slug} not found` } }) + } + req.body.server = server + next() + }) + + router.post('/index', auth.required, async function (req: any, res) { + const user = await User.findById(req.payload.id) + if (!user) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.isAdmin() && !user.authorized) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (user.processing) { + return res.sendStatus(apiCode.forbidden) + } + + const server = + await Server.findOne({ slug: req.body.server }).populate('author') + if (!server) { + return res.sendStatus(apiCode.not_found) + .json({ errors: { errors: 'Server not found' } }) + } + if ((server.author.username !== user.username) && (!user.isAdmin())) { + console.log(server.author.username) + console.log(user.username) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + + const serverPath = path.join('uploads', server.author.username, server.slug) + + const groups = + await fs.promises.readFile(path.join(serverPath, 'exercises/index.json'), + { encoding: 'utf8' }) + .then(JSON.parse) + .catch(err => { + if (err.code === 'ENOENT') { return [] } else { throw err } + }) as { [id: string]: { exercises: string[] }} + + const usedList = Object.values(groups).flatMap(group => group.exercises) + const exercisesList = + await fs.promises.readdir(path.join(serverPath, 'exercises')) + .then(files => files.filter(file => !usedList.includes(file))) + .catch(err => { + if (err.code === 'ENOENT') { return [] } else { throw err } + }) + return res.json({ exercisesList, groups }) + }) + + router.post('/check', auth.required, upload.single('file'), async function (req: any, res) { + const user = await User.findById(req.payload.id) + if (!user) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.isAdmin() && !user.authorized) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (user.processing) { + return res.sendStatus(apiCode.forbidden) + } + const server = + await Server.findOne({ slug: req.body.server }).populate('author') + if (!server) { + return res.sendStatus(apiCode.not_found) + .json({ errors: { errors: 'Server not found' } }) + } + if ((server.author.username !== user.username) && (!user.isAdmin())) { + console.log(server.author.username) + console.log(user.username) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!req.file) { + console.log('No file received') + return res.send({ success: false }) + } + console.log('file received') + const allowedMimetypes = ['zip', 'octet-stream', 'x-zip-compressed'] + .map(typ => 'application/'.concat(typ)) + if (!allowedMimetypes.includes(req.file.mimetype)) { + console.error(`Bad file Format : ${req.file.mimetype}`) + console.error('Expected .zip') + return res.status(apiCode.error) + .json({ + errors: { file: `must be exercises.zip, found ${req.file.mimetype}` } + }) + } + + const serverPath = path.join('uploads', server.author.username, server.slug) + fs.mkdirSync(serverPath, { recursive: true }) + const files = + (await archive.unzip(inPathData(req.archivePath), outBufferData)) + .filter(file => file.zipPath.startsWith('exercises')) + fs.unlinkSync(req.archivePath) + await Promise.all(files.map(async file => + convertFileData(file, outPathData(path.join(serverPath, file.zipPath))))) + console.log(files) + + // Frontend actually need a list of exercises as directories + const exercisesPath = path.join(serverPath, 'exercises') + const dirs = fs.readdirSync(exercisesPath, { withFileTypes: true }) + .filter(dirent => dirent.isDirectory()) + return res.json({ name: dirs }) + }) + + router.post('/full', auth.required, upload.single('file'), async function (req: any, res) { + const user = await User.findById(req.payload.id) + if (!user) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.isAdmin() && !user.authorized) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (user.processing) { + return res.sendStatus(apiCode.forbidden) + } -import auth from './auth'; + const server = + await Server.findOne({ slug: req.body.server }).populate('author') + if (!server) { + return res.sendStatus(apiCode.not_found) + .json({ errors: { errors: 'Server not found' } }) + } + if ((server.author.username !== user.username) && (!user.isAdmin())) { + console.log(server.author.username) + console.log(user.username) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!req.file) { + console.log('No file received') + return res.send({ + success: false + }) + } -import * as upload_functions from '../lib/upload_functions'; -import upload_errors from '../lib/errors'; + const allowedMimetypes = ['zip', 'octet-stream', 'x-zip-compressed'] + .map(mime => `application/${mime}`) + if (!allowedMimetypes.includes(req.file.mimetype)) { + console.error(`Bad file Format : ${req.file.mimetype}`) + console.error('\nExpected .zip') + return res.status(apiCode.error) + .json({ + errors: { file: 'must be exercises.zip found ' + req.file.mimetype } + }) + } + + const serverPath = path.join('uploads', server.author.username, server.slug) + const exercisesPath = path.join(serverPath, 'exercises') + fs.mkdirSync(exercisesPath, { recursive: true }) + + const files = await archive.unzip(inPathData(req.archivePath), + outBufferData) as BufferFileData[] + fs.unlinkSync(req.archivePath) + + await Promise.all(files + .filter(file => file.zipPath.startsWith('repository/exercises')) + .map(file => { + const filePath = path.join(exercisesPath, path.basename(file.zipPath)) + fs.mkdirSync(path.dirname(file.zipPath), { recursive: true }) + return fs.promises.writeFile(filePath, file.input) + })) + + const repoFiles = + files.filter(file => file.zipPath.startsWith('repository')) + const repoArchiveData = await archive.zip(repoFiles, outBufferData) + await cloud.uploadObject(server.slug, 'repository.zip', repoArchiveData) + + const syncFiles = files.filter(file => file.zipPath.startsWith('sync')) + if (syncFiles.length > 0) { + const syncArchiveData = await archive.zip(syncFiles, outBufferData) + await cloud.uploadObject(server.slug, 'sync.zip', syncArchiveData) + } + return res.sendStatus(apiCode.ok) + }) -import api_code from '../configs/api_code'; -import { CloudService } from 'cloud/CloudService'; -import { DataKind, outPathData } from 'utils/Data'; + router.post('/url', auth.required, async function (req: any, res) { + const user = await User.findById(req.payload.id) + if (!user) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.isAdmin() && !user.authorized) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (user.processing) { + return res.sendStatus(apiCode.forbidden) + } + + const server = await Server.findOne({ slug: req.body.server }).populate('author') + if (!server) { + return res.sendStatus(apiCode.not_found) + .json({ errors: { errors: 'Server not found' } }) + } + if ((server.author.username !== user.username) && (!user.isAdmin())) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } -const dirPath = './uploads/'; -var destPath = ''; + const fileUrl = new URL(req.body.url.url) + fileUrl.pathname = path.join(fileUrl.pathname, '/archive/master.zip') + + const archiveBuffer = + await axios.get(fileUrl.toString(), { responseType: 'arraybuffer' }) + .then(res => res.data as Buffer) + + const files = + (await archive.unzip(inBufferData(archiveBuffer), outBufferData)) + .filter(file => file.zipPath.includes('exercises')) + .map(file => { + const zipPath = file.zipPath.substring(file.zipPath.indexOf('/') + 1) + return fileData(file, zipPath) + }) + + const serverPath = path.join('uploads', server.author.username, server.slug) + await Promise.all(files.map(async file => { + const filePath = path.join(serverPath, file.zipPath) + fs.mkdirSync(path.dirname(filePath)) + return fs.promises.writeFile(filePath, file.input) + })) + console.log(files) + + // Frontend actually need a list of exercises as directories + const exercisesPath = path.join(serverPath, 'exercises') + const dirs = fs.readdirSync(exercisesPath, { withFileTypes: true }) + .filter(dirent => dirent.isDirectory()) + return res.json({ name: dirs }) + }) -const save_folder = 'save/'; -const archive_folder = 'archive/'; -const download_folder = 'download/'; -const safe_folder = 'exercises/'; -const dirt_folder = 'sandbox/'; + router.post('/send', auth.required, async function (req: any, res: any) { + const user = await User.findById(req.payload.id) + if (!user) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.isAdmin() && !user.authorized) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (user.processing) { return res.sendStatus(apiCode.forbidden) } -/** Used when uploading a "ready to launch" archive */ -const uploadDir = 'upload/'; + const server = + await Server.findOne({ slug: req.body.server }).populate('author') + if (!server) { + return res.sendStatus(apiCode.not_found) + .json({ errors: { errors: 'Not found' } }) + } + if ((server.author.username !== user.username) && (!user.isAdmin())) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } -const indexJSON = 'index.json'; -const archive_extension = 'zip'; + await user.startProcessing() + console.log('user.processing : ' + user.processing) -const repositoryName = 'repository'; -const repositoryDir = repositoryName + '/'; -const repositoryArchive = repositoryName + '.' + archive_extension; -const syncName = 'sync'; -const syncDir = syncName + '/'; -const syncArchive = syncName + '.' + archive_extension; + const serverPath = path.join('uploads', server.author.username, server.slug) + const exercisesPath = path.join(serverPath, 'exercises') -const exercisesDir = 'exercises/'; + const trash: string[] = req.body.trash + await Promise.all(trash.map(async exercise => + fs.promises.rm(path.join(exercisesPath, exercise), { recursive: true }))) -var User = mongoose.model('User'); -var Server = mongoose.model('Server'); + const indexPath = path.join(exercisesPath, 'index.json') + const groups = + req.body.groups as { [id: string]: { title: string, exercises: string[] }} + const indexData = JSON.stringify(groups, null, 4) -let storage = multer.diskStorage({ - destination: (req : any, file : any, cb : any) => { - cb(null, dirPath); - }, - filename: (req : any, file : any, cb : any) => { - destPath = path.extname(file.originalname); - cb(null, destPath); + if (Object.keys(groups).length === 0) { + return res.status(400).send({ errors: { file: ': No groups received' } }) } -}); -let upload = multer({ storage: storage }); + await fs.promises.writeFile(indexPath, indexData, 'utf8') -export function uploadAPI(cloud: CloudService) { - const router = Router(); + const safePathData = + fileData(inPathData(exercisesPath), exercisesPath) as PathFileData + const zipData = await archive.zipFromDir(safePathData, outBufferData) + cloud.uploadObject(server.slug, 'repository.zip', zipData) - // Preload server objects on routes with ':server' - router.param('server', function(req: any, res, next, slug) { - Server.findOne({ slug: slug }) - .populate('author') - .then(function(server: any) { - if (!server) { return res.sendStatus(api_code.not_found).json({ errors: { errors: 'Server ' + slug + ' not found' } }); } - - req.server = server; - - return next(); - }).catch(next); - }); - - router.get('/', auth.required, function(req: any, res) { - res.end('file catcher example'); - }); - - router.post('/index', auth.required, function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (!user) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (!user.isAdmin() && !user.authorized) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (user.processing) { return res.sendStatus(api_code.forbidden); } - Server.findOne({ slug: req.body.server }) - .populate('author') - .then(function(server: any) { - if (!server) { return res.sendStatus(api_code.not_found).json({ errors: { errors: 'Server not found' } }); } - if ((server.author.username !== user.username) && (!user.isAdmin())) { - console.log(server.author.username); - console.log(user.username); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - var dest_path = dirPath + server.author.username + '/' + server.slug + '/'; - upload_functions.loadIndexJson(dest_path + save_folder) - .catch((error: any) => { - if (error.code === 'ENOENT') { - return []; - } else { - throw error; - } - }) - .then((groups: any) => { - upload_functions.checkFiles(dest_path + dirt_folder).then((files_sended: any) => { - var files: any = []; - upload_functions.checkFiles(dest_path + safe_folder).then((files_saved: any) => { - files_saved.forEach((element: any) => { - if (!files_sended.includes(element)) { - files.push(element); - } - }); - return res.json({ - name: files, - group: groups - }); - }, (err: any) => { - console.log('Error checkFiles !: ' + err); - return res.status(api_code.error).json({ errors: { errors: err.message } }); - }); - }, (err: any) => { - console.log('Error checkFiles !: ' + err); - return res.status(api_code.error).json({ errors: { errors: err.message } }); - }); - }, (err: any) => { - console.log('Error loading tabofName !: ' + err); - return res.status(api_code.error).json({ errors: { errors: err.message } }); - }); - }).catch(next); - }).catch(next); - }); - - router.post('/check', auth.required, upload.single('file'), function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (!user) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (!user.isAdmin() && !user.authorized) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (user.processing) { return res.sendStatus(api_code.forbidden); } - Server.findOne({ slug: req.body.server }) - .populate('author') - .then(function(server: any) { - if (!server) { return res.sendStatus(api_code.not_found).json({ errors: { errors: 'Server not found' } }); } - if ((server.author.username !== user.username) && (!user.isAdmin())) { - console.log(server.author.username); - console.log(user.username); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - if (!req.file) { - console.log("No file received"); - return res.send({ - success: false - }); - } else { - var dest_path = dirPath + server.author.username + '/'; - var source_path = dirPath + destPath; - var mimetype = req.file.mimetype; - if (mimetype === 'application/zip' || - mimetype === 'application/octet-stream' || - mimetype === 'application/x-zip-compressed') { - console.log('file received'); - upload_functions.createArbo(dest_path, server.slug + '/', safe_folder, dirt_folder, save_folder, download_folder).then((response: any) => { - upload_functions.archive_traitement(dest_path + server.slug + '/', source_path, archive_folder, safe_folder, '').then((files: any) => { - console.log(files); - return res.json({ - name: files, - }); - }, (err: any) => { - console.log('Error archive traitement !: ' + err); - return res.status(api_code.error).json({ errors: { errors: err.message } }); - }); - }, (err: any) => { - console.log('Error createArbo !: ' + err); - return res.status(api_code.error).json({ errors: { errors: err.message } }); - }); - } else { - console.error('Bad file Format : ' + req.file.mimetype + '\nExpected .zip'); - return res.status(api_code.error).json({ errors: { file: 'must be exercises.zip found ' + req.file.mimetype } }); - } - } - }).catch(next); - }).catch(next); - }); - - - router.post('/full', auth.required, upload.single('file'), function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (!user) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (!user.isAdmin() && !user.authorized) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (user.processing) { return res.sendStatus(api_code.forbidden); } - Server.findOne({ slug: req.body.server }) - .populate('author') - .then(function(server: any) { - if (!server) { return res.sendStatus(api_code.not_found).json({ errors: { errors: 'Server not found' } }); } - if ((server.author.username !== user.username) && (!user.isAdmin())) { - console.log(server.author.username); - console.log(user.username); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - if (!req.file) { - console.log("No file received"); - return res.send({ - success: false - }); - } else { - let userDirPath = dirPath + server.author.username + '/'; - let serverDir = server.slug + '/'; - let serverDirPath = userDirPath + serverDir; - let archiveFilePath = dirPath + destPath; - - // ./uploads/user/server/upload - let uploadDirPath = serverDirPath + uploadDir; - - // ./uploads/user/server/upload/archive - let swiftDirPath = uploadDirPath + archive_folder; - - let repositoryDirPath = uploadDirPath + repositoryDir; - let repositoryNamePath = swiftDirPath + repositoryName; - let syncDirPath = uploadDirPath + syncDir; - let syncNamePath = swiftDirPath + syncName; - let exercisesPath = repositoryDirPath + exercisesDir; - - let indexJSONPath = exercisesPath + indexJSON; - let saveIndexJSONPath = serverDirPath + save_folder + indexJSON; - let safePath = serverDirPath + safe_folder; - let dirtPath = serverDirPath + dirt_folder; - - let mimetype = req.file.mimetype; - if (mimetype === 'application/zip' || - mimetype === 'application/octet-stream' || - mimetype === 'application/x-zip-compressed') { - console.log('full archive file received'); - upload_functions.createArbo(userDirPath, serverDir, safe_folder, - dirt_folder, save_folder, download_folder) - .catch((err: any) => upload_errors.wrap_error('createArbo', api_code.error, err)) - - .then(() => upload_functions.removeDir(uploadDirPath)) - .catch((err: any) => upload_errors.wrap_error('removeDir', api_code.error, err)) - - .then(() => upload_functions.createDir(uploadDirPath)) - .then(() => upload_functions.createDir(swiftDirPath)) - .catch((err: any) => upload_errors.wrap_error('createDir', api_code.error, err)) - - .then(() => upload_functions.desarchived(uploadDirPath, archiveFilePath)) - .catch((err: any) => upload_errors.wrap_error('desarchived', api_code.error, err)) - - .then(() => upload_functions.removeDir(archiveFilePath)) - - .then(() => upload_functions.copyFile(indexJSONPath, saveIndexJSONPath)) - .catch((err: any) => upload_errors.wrap_error('copyFile', api_code.error, err)) - - .then(() => upload_functions.copyDir(exercisesPath, safePath)) - .then(() => upload_functions.copyDir(exercisesPath, dirtPath)) - .catch((err: any) => upload_errors.wrap_error('copyDir', api_code.error, err)) - - .then(() => upload_functions.createArchiveFromDirectory(repositoryDirPath, repositoryDir, - archive_extension, repositoryNamePath)) - .catch((err: any) => upload_errors.wrap_error('createArchiveFromDirectory sync', api_code.error, err)) - - .then(() => cloud.uploadObject(server.slug, repositoryArchive, { - kind: DataKind.Path, - input: path.join(swiftDirPath, repositoryArchive) - })) - .catch((err: any) => upload_errors.wrap_error('cloud.uploadObject', api_code.error, err)) - .then(() => upload_functions.fileExists(syncDirPath)) - .then(async (syncExists: any) => { - console.log("syncExists:", syncExists); - if (syncExists) { - await upload_functions.createArchiveFromDirectory(syncDirPath, syncDir, - archive_extension, syncNamePath) - .catch((err: any) => upload_errors.wrap_error('createArchiveFromDirectory sync', - api_code.error, err)) - - await cloud.uploadObject(server.slug, syncArchive, { - kind: DataKind.Path, - input: path.join(swiftDirPath, syncArchive) - }) - .catch((err: any) => upload_errors.wrap_error('cloud.uploadObject', api_code.error, err)) - } - }) - .then(() => res.sendStatus(api_code.ok)) - .catch((err: any) => upload_errors.unwrap_error(res, err)); - } else { - console.error('Bad file Format : ' + req.file.mimetype + '\nExpected .zip'); - return res.status(api_code.error) - .json({ errors: { file: 'must be exercises.zip found ' + req.file.mimetype } }); - } - } - }).catch(next); - }).catch(next); - }); - - - router.post('/url', auth.required, function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (!user) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (!user.isAdmin() && !user.authorized) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (user.processing) { return res.sendStatus(api_code.forbidden); } - Server.findOne({ slug: req.body.server }) - .populate('author') - .then(function(server: any) { - if (!server) { return res.sendStatus(api_code.not_found).json({ errors: { errors: 'Server not found' } }); } - if ((server.author.username !== user.username) && (!user.isAdmin())) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - console.log(req.body); - var file_url = req.body.url.url + '/archive/master.zip'; - var DOWNLOAD_DIR = './downloads/'; - var dest_path = dirPath + server.author.username + '/'; - if (upload_functions.parse_url(file_url) !== 'github.com') { - return res.status(api_code.error).json({ errors: { errors: ': URL invalid' } }); - } - upload_functions.createArbo(dest_path, server.slug + '/', safe_folder, dirt_folder, save_folder, download_folder).then((response: any) => { - upload_functions.createDir(dest_path + server.slug + '/' + DOWNLOAD_DIR).then(() => { - upload_functions.download_from_url(file_url, dest_path + server.slug + '/' + DOWNLOAD_DIR).then((source_path: any) => { - upload_functions.archive_traitement(dest_path + server.slug + '/', source_path, archive_folder, safe_folder, '/exercises').then((files: any) => { - console.log(files); - return res.json({ - name: files, - }); - }, (err: any) => { - console.log('Error archive traitement !: ' + err); - return res.status(api_code.error).json({ errors: err }); - }); - }, (err: any) => { - console.log('Error createArbo !: ' + err); - return res.status(api_code.error).json({ errors: { errors: err.message } }); - }); - }, (err: any) => { - console.log('Error getRepo !: ' + err); - return res.status(api_code.error).json({ errors: { errors: err.message } }); - }); - }, (err: any) => { - console.log('Error download from url !: ' + err); - var message = upload_errors.wget_error(err.code) + err.message; - return res.status(api_code.error).send({ errors: { message } }); - }); - }).catch(next); - }).catch(next); - }); - - - router.post('/send', auth.required, function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (!user) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (!user.isAdmin() && !user.authorized) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (user.processing) { return res.sendStatus(api_code.forbidden); } - Server.findOne({ slug: req.body.server }) - .populate('author') - .then(function(server: any) { - if (!server) { return res.sendStatus(api_code.not_found).json({ errors: { errors: 'Not found' } }); } - if ((server.author.username !== user.username) && (!user.isAdmin())) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - var dir = './uploads/' + server.author.username + '/' + server.slug + '/'; - var tabOfName = req.body.list; - if (!tabOfName || tabOfName === undefined || !tabOfName.length || (tabOfName.length == 1 && tabOfName[0].length < 2)) { - return res.status(api_code.error).send({ errors: { file: ": No groups received" } }); - } - if (upload_errors.group_duplicate(tabOfName)) { - return res.status(api_code.error).send({ errors: { file: ": Error in groups names, duplicate name" } }); - } - user.startProcessing() - .then(() => console.log('user.processing : ' + user.processing)) - .then(async () => { - let trash = req.body.trash; - console.log("trash"); - console.log(trash); - if (Array.isArray(trash)) { - await Promise.all(trash.map(exercise => { - let safeExercisePath = - path.resolve(dir, safe_folder, exercise), - dirtExercisePath = - path.resolve(dir, dirt_folder, exercise); - return upload_functions.removeDir(safeExercisePath) - .catch((err: any) => upload_errors.wrap_error('removeDir', api_code.error, err)) - .then(() => console.log(safeExercisePath + - ' removed')) - .then(() => upload_functions.removeDir(dirtExercisePath)) - .catch((err: any) => upload_errors.wrap_error('removeDir', api_code.error, err)) - .then(() => console.log(dirtExercisePath + - ' removed')); - })); - - } - }) - .then(() => upload_functions.checkFiles(dir + safe_folder)) - .catch((err: any) => upload_errors.wrap_error('checkFiles', api_code.error, err)) - .then((files: any) => - upload_functions.copyDir(dir + safe_folder, dir + dirt_folder) - .catch((err: any) => upload_errors.wrap_error('copyDir', api_code.error, err)) - .then(() => upload_functions.delete_useless_files(req.body.useless, dir + dirt_folder, - tabOfName, files)) - .catch((err: any) => upload_errors.wrap_error('delete_useless_files', api_code.error, err))) - .then((tabOfName_bis: any) => upload_functions.create_new_tabOfName(dir + save_folder, - dir + dirt_folder, - tabOfName_bis)) - .catch((err: any) => upload_errors.wrap_error('create_new_tabOfName', api_code.error, err)) - .then((new_tabOfName: any) => { - let sourcePath = dir + dirt_folder; - let destPath = repositoryDir + exercisesDir; - let archivePath = sourcePath + archive_folder; - let repositoryPath = archivePath + repositoryName; - upload_functions.create_indexJSON(dir + dirt_folder + 'index.json', new_tabOfName) - .catch((err: any) => upload_errors.wrap_error('create_indexJSON', api_code.error, err)) - - .then(() => upload_functions.createDir(dir + dirt_folder + archive_folder)) - .catch((err: any) => upload_errors.wrap_error('createDir', api_code.error, err)) - - .then(() => upload_functions.copyFile(dir + save_folder + indexJSON, - sourcePath + indexJSON)) - .catch((err: any) => upload_errors.wrap_error('copyFile index.json', api_code.error, err)) - - .then(() => upload_functions.createArchiveFromDirectory(sourcePath, destPath, - archive_extension, - repositoryPath)) - .catch((err: any) => upload_errors.wrap_error('createArchiveFromDirectory', api_code.error, err)) - - .then(() => cloud.uploadObject(server.slug, repositoryArchive, { - kind: DataKind.Path, - input: path.join(archivePath, repositoryArchive) - })) - .catch((err: any) => upload_errors.wrap_error('cloud.uploadObject', api_code.error, err)) - - .then(() => upload_functions.removeDir(archivePath)) - .catch((err: any) => upload_errors.wrap_error('archivePath', api_code.error, err)) - - .finally(() => user.endProcessing()) - .finally(() => console.log('user.processing : ' + user.processing)) - .then(() => res.send({ success: true, message: 'ok' })) - .catch((err: any) => upload_errors.unwrap_error(res, err)); - }).catch(next); - }).catch(next); - }); - }); - - router.post('/download/:server', auth.required, function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (!user) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (!user.isAdmin() && !user.authorized) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (user.processing) { return res.sendStatus(api_code.forbidden); } - var server = req.server; - if ((server.author.username !== user.username) && (!user.isAdmin())) { - console.log(server.author.username); - console.log(user.username); - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); - } - user.startProcessing().then(async () => { - console.log('user.processing : ' + user.processing); - const serverUploadDir = path.join(dirPath, server.author.username) - const dest_path = path.join(serverUploadDir, server.slug) - - const isSaneTarget = - (['all', 'sync', 'repository'].includes(req.body.target)) - const target = isSaneTarget ? req.body.target : 'all'; - - await upload_functions.createArbo(dirPath + server.author.username + '/', server.slug + '/', safe_folder, dirt_folder, save_folder, download_folder) - .catch((err: any) => upload_errors.wrap_error('createArbo', api_code.error, err)) - - if(target === 'all') { - const downloadPath = path.join(dest_path, download_folder) - await cloud.downloadAllObjs(server.slug, outPathData(downloadPath)) - } else { - const targetArchive = target + '.zip' - await cloud.downloadObject(server.slug, targetArchive, { - kind: DataKind.Path, - output: path.join(dest_path, download_folder, targetArchive) - }) - } - var folderName = target; - if (folderName === 'all') { - let downloadPathDir = path.join(dest_path, download_folder) - let allPath = path.join(downloadPathDir, folderName) - let allPathDir = allPath + '/'; - upload_functions.removeDir(allPath + '.' + archive_extension) - .then(() => upload_functions.removeDir(allPathDir)) - .catch((err: any) => upload_errors.wrap_error('removeDir', api_code.error, err)) - - .then(() => upload_functions.createDir(allPathDir)) - .catch((err: any) => upload_errors.wrap_error('createDir', api_code.error, err)) - - .then(() => upload_functions.desarchived(allPathDir, downloadPathDir + repositoryArchive)) - .then(() => upload_functions.fileExists(downloadPathDir + syncArchive)) - .then((syncExist: any) => (syncExist) ? upload_functions.desarchived(allPathDir, - downloadPathDir + syncArchive) - : undefined) - .catch((err: any) => upload_errors.wrap_error('desarchived', api_code.error, err)) - - .then(() => upload_functions.createArchiveFromDirectory(allPathDir, '', - archive_extension, allPath)) - .catch((err: any) => upload_errors.wrap_error('createArchiveFromDirectory', api_code.error, err)) - - .then(() => user.endProcessing()) - .then(() => console.log('user.processing : ' + user.processing)) - .then(() => res.sendFile(path.resolve(allPath + '.' + archive_extension))) - - .catch((err: any) => upload_errors.unwrap_error(res, err)); - } else { - user.endProcessing().then(() => { - console.log('user.processing : ' + user.processing); - const fileArchive = path.join(dest_path, download_folder, - folderName + '.' + archive_extension) - res.sendFile(path.resolve(fileArchive)) - }); - } - }).catch(next) - }) + await user.endProcessing() + console.log(`user.processing : ${user.processing}`) + return res.send({ success: true, message: 'ok' }) + }) + + router.post('/download/:server', auth.required, async function (req: any, res) { + const user = await User.findById(req.payload.id) + if (!user) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.isAdmin() && !user.authorized) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (user.processing) { return res.sendStatus(apiCode.forbidden) } + + const server = req.body.server + if ((server.author.username !== user.username) && (!user.isAdmin())) { + console.log(server.author.username) + console.log(user.username) + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + + await user.startProcessing() + console.log('user.processing : ' + user.processing) + + const isSaneTarget = + (['all', 'sync', 'repository'].includes(req.body.target)) + const target = isSaneTarget ? req.body.target : 'all' + + if (target === 'all') { + const zips = await cloud.downloadAllObjs(server.slug, outBufferData) + const files = + await Promise.all(zips.map(zip => archive.unzip(zip, outBufferData))) + .then(filesLists => filesLists.flat()) + const allZip = await archive.zip(files, outBufferData) + + return res.send(allZip.input) + } else { + const zip = + await cloud.downloadObject(server.slug, `${target}.zip`, outBufferData) + return res.send(zip.input) + } }) return router diff --git a/BackEnd/src/controllers/users.ts b/BackEnd/src/controllers/users.ts index c89f030..4d0289c 100644 --- a/BackEnd/src/controllers/users.ts +++ b/BackEnd/src/controllers/users.ts @@ -1,434 +1,379 @@ import { Router } from 'express' +import fs from 'fs' import path from 'path' -var passport = require('passport'); -import auth from './auth'; +import auth from './auth' -import * as server_functions from '../lib/server_functions'; -import * as upload_functions from '../lib/upload_functions'; -import * as global_functions from '../lib/global_functions'; +// eslint-disable-next-line +import * as server_functions from '../lib/server_functions' -import api_code from '../configs/api_code'; +import apiCode from '../configs/api_code' import { CloudService } from 'cloud/CloudService' import { User } from 'models' +import passport from 'passport' // can delegate cloud API call to serverAPI ? -export function userAPI(cloud: CloudService) { - const router = Router(); - - router.get('/user', auth.required, function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (!user) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - - return res.json({ user: user.toAuthJSON() }); - }).catch(next); - }); - - router.get('/users', auth.required, function(req: any, res, next) { - var query: any = {}; - var limit = 20; - var offset = 0; - console.log(' req.query.limit ' + req.query.limit); - console.log(' req.query.offset ' + req.query.offset); - console.log(' req.query.active ' + req.query.active); - console.log(' req.query.authorized ' + req.query.authorized); +export function userAPI (cloud: CloudService) { + const router = Router() + + router.get('/user', auth.required, async function (req: any, res) { + const user = await User.findById(req.payload.id) + if (!user) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + + return res.json({ user: user.toAuthJSON() }) + }) + + router.get('/users', auth.required, async function (req: any, res, next) { + const query: any = {} + let limit = 20 + let offset = 0 + console.log(' req.query.limit ' + req.query.limit) + console.log(' req.query.offset ' + req.query.offset) + console.log(' req.query.active ' + req.query.active) + console.log(' req.query.authorized ' + req.query.authorized) if (typeof req.query.limit !== 'undefined') { - limit = req.query.limit; + limit = req.query.limit } - if (typeof req.query.offset !== 'undefined') { - offset = req.query.offset; + offset = req.query.offset } - if (typeof req.query.active !== 'undefined') { - query.active = req.query.active; + query.active = req.query.active } - if (typeof req.query.authorized !== 'undefined') { - query.authorized = req.query.authorized; + query.authorized = req.query.authorized } - User.findById(req.payload.id).then(function(user: any) { - if (!user) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (user.isAdmin()) { + const user = await User.findById(req.payload.id) + if (!user || !user.isAdmin()) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (user.isAdmin()) { + const [users, usersCount] = await user.findAllUsers(query, limit, offset) + return res.json({ users: users, usersCount: usersCount }) + } + }) - return user.findAllUsers(query, limit, offset).then(function(results: any) { - var users = results[0]; - var usersCount = results[1]; + router.put('/user', auth.required, async function (req: any, res, next) { + const user = await User.findById(req.payload.id) + if (!user) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.active) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.isAdmin() && !user.authorized) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } - return res.json({ - users: users, - usersCount: usersCount - }); - }); - } else { - return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); + const userToModify = + (user.isAdmin() && (req.body.userBase.username !== 'undefined')) + ? (await User.find({ username: req.body.userBase.username }))[0] + : user + + if (userToModify !== 'undefined') { + // only update fields that were actually passed... + // if (typeof req.body.user.username !== 'undefined') { // may be useless + // userToMdify.username = req.body.user.username; + // } + if ((typeof req.body.user.email !== 'undefined')) { + userToModify.email = req.body.user.email } - }).catch(next); - }); - - router.put('/user', auth.required, function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (!user) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (!user.active) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (!user.isAdmin() && !user.authorized) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - - var userToMdify: any = 'undefined'; - - if (user.isAdmin() && (req.body.userBase.username !== 'undefined')) { - User.find({ username: req.body.userBase.username }).then(function(response: any) { - userToMdify = response[0]; - }); + if (typeof req.body.user.description !== 'undefined') { + userToModify.description = req.body.user.description } - else { - userToMdify = user; + if (typeof req.body.user.place !== 'undefined') { + userToModify.place = req.body.user.place } + if (typeof req.body.user.goal !== 'undefined') { + userToModify.goal = req.body.user.goal + } + if (typeof req.body.user.image !== 'undefined') { + userToModify.image = req.body.user.image + } + await userToModify.save() + return res.json({ user: userToModify.toAuthJSON() }) + } + }) - var userInChange = setInterval(function() { - if (userToMdify !== 'undefined') { - // only update fields that were actually passed... - // if (typeof req.body.user.username !== 'undefined') { // may be useless - // userToMdify.username = req.body.user.username; - // } - if ((typeof req.body.user.email !== 'undefined')) { - userToMdify.email = req.body.user.email; - } - if (typeof req.body.user.description !== 'undefined') { - userToMdify.description = req.body.user.description; - } - if (typeof req.body.user.place !== 'undefined') { - userToMdify.place = req.body.user.place; - } - if (typeof req.body.user.goal !== 'undefined') { - userToMdify.goal = req.body.user.goal; - } - if (typeof req.body.user.image !== 'undefined') { - userToMdify.image = req.body.user.image; - } - clearInterval(userInChange); - return userToMdify.save().then(function() { - return res.json({ user: userToMdify.toAuthJSON() }); - }); - } - }, 300); - }).catch(next); - }); - - router.post('/users/login', function(req: any, res, next) { + router.post('/users/login', async function (req: any, res, next) { if (!req.body.user.email) { - return res.status(api_code.error).json({ errors: { email: "can't be blank" } }); + return res.status(apiCode.error) + .json({ errors: { email: "can't be blank" } }) } - if (!req.body.user.password) { - return res.status(api_code.error).json({ errors: { password: "can't be blank" } }); + return res.status(apiCode.error) + .json({ errors: { password: "can't be blank" } }) } - passport.authenticate('local', { session: false }, function(err: any, user: any, info: any) { - if (err) { return next(err); } - + // TODO: use simple way to check password (with hash) + function cb (err: any, user: any, info: any) { + if (err) { return next(err) } if (user) { - user.token = user.generateJWT(); - return res.json({ user: user.toAuthJSON() }); + user.token = user.generateJWT() + return res.json({ user: user.toAuthJSON() }) } else { - return res.status(api_code.error).json(info); + return res.status(apiCode.error).json(info) } - })(req, res, next); - }); - - router.post('/reset-password', auth.required, function(req: any, res, next) { + } + passport.authenticate('local', { session: false }, cb)(req, res, next) + }) + router.post('/reset-password', auth.required, async function (req: any, res) { if (!req.body.reset.new_password) { - return res.status(api_code.error).json({ errors: { password: "can't be blank" } }); + return res.status(apiCode.error) + .json({ errors: { password: "can't be blank" } }) } - if (!req.body.reset.new_password_verification) { - return res.status(api_code.error).json({ errors: { password: "can't be blank" } }); + const user = await User.findById(req.payload.id) + if (!user) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.active) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.isAdmin() && !user.authorized) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!req.body.user.email) { + return res.status(apiCode.error) + .json({ errors: { email: "can't be blank" } }) } - if (req.body.reset.new_password !== req.body.reset.new_password_verification) { - return res.status(api_code.error).json({ errors: { password: "verification mismatch" } }); + if (req.body.user.email !== user.email) { + return res.status(apiCode.error) + .json({ errors: { email: 'does not correspond' } }) + } + if (!req.body.user.password) { + return res.status(apiCode.error) + .json({ errors: { password: "can't be blank" } }) } - User.findById(req.payload.id).then(function(user: any) { - if (!user) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } + if (!user.validPassword(req.body.user.password)) { + return res.status(apiCode.error) + .json({ errors: { password: 'does not correspond' } }) + } - if (!user.active) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (!user.isAdmin() && !user.authorized) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } + user.setPassword(req.body.reset.new_password) - if (!req.body.user.email) { - return res.status(api_code.error).json({ errors: { email: "can't be blank" } }); - } + await user.save() + return res.json({ user: user.toAuthJSON() }) + }) - if (req.body.user.email !== user.email) { - return res.status(api_code.error).json({ errors: { email: "does not correspond" } }); - } + // disable or enable an user + router.post('/users/disable', auth.required, async function (req: any, res, next) { + const user = await User.findById(req.payload.id) + if (!user) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (!user.authorized && !user.isAdmin()) { + return res.sendStatus(apiCode.forbidden) + .json({ errors: { errors: 'Unauthorized' } }) + } + if (user.processing) { + return res.sendStatus(apiCode.forbidden) + } - if (!req.body.user.password) { - return res.status(api_code.error).json({ errors: { password: "can't be blank" } }); - } + if (!req.body.user.email) { + return res.status(apiCode.error) + .json({ errors: { email: "can't be blank" } }) + } - if (!user.validPassword(req.body.user.password)) { - return res.status(api_code.error).json({ errors: { password: "does not correspond" } }); - } + if (req.body.user.email !== user.email) { + return res.status(apiCode.error) + .json({ errors: { email: 'does not correspond' } }) + } - user.setPassword(req.body.reset.new_password); + if (!req.body.user.password) { + return res.status(apiCode.error) + .json({ errors: { password: "can't be blank" } }) + } - return user.save().then(function() { - return res.json({ user: user.toAuthJSON() }); - }); - }).catch(next); - }); + if (!user.validPassword(req.body.user.password)) { + return res.status(apiCode.error) + .json({ errors: { password: 'does not correspond' } }) + } - //disable or enable an user - router.post('/users/disable', auth.required, function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (!user) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (!user.authorized && !user.isAdmin()) { return res.sendStatus(api_code.forbidden).json({ errors: { errors: 'Unauthorized' } }); } - if (user.processing) { return res.sendStatus(api_code.forbidden); } + if (!req.body.disable.password_verification) { + return res.status(apiCode.error) + .json({ errors: { password: "can't be blank" } }) + } - if (!req.body.user.email) { - return res.status(api_code.error).json({ errors: { email: "can't be blank" } }); - } + if (req.body.user.password !== req.body.disable.password_verification) { + return res.status(apiCode.error) + .json({ errors: { password: 'verification mismatch' } }) + } + if (!req.body.disable.username_verification) { + return res.status(apiCode.error) + .json({ errors: { username: "can't be blank" } }) + } - if (req.body.user.email !== user.email) { - return res.status(api_code.error).json({ errors: { email: "does not correspond" } }); + if (!user.isAdmin()) { + if (req.body.disable.username_verification !== user.username) { + return res.status(apiCode.error) + .json({ errors: { username: 'verification mismatch' } }) } + } - if (!req.body.user.password) { - return res.status(api_code.error).json({ errors: { password: "can't be blank" } }); - } + const [author] = + await user.findAnUser(req.body.disable.username_verification) - if (!user.validPassword(req.body.user.password)) { - return res.status(api_code.error).json({ errors: { password: "does not correspond" } }); - } + const [servers] = + await user.findAllServersOfAnUser(req.query, author, req.payload) - if (!req.body.disable.password_verification) { - return res.status(api_code.error).json({ errors: { password: "can't be blank" } }); + await Promise.all(servers.map(async (server: any) => { + if (server.active && user.active) { + console.log('preparing shut_off') + const namespace = 'default' + await server_functions.removekubelink(server.slug, namespace) + server.active = false + return server.save() } + })) + + console.log('author = ' + author) + console.log('all servers are done') + author.active = !author.active + console.log('user status up to date') + await author.save() + + if (!user.isAdmin()) { + return res.json({ user: author.toAuthJSON() }) + } else { + return res.json({ user: user.toAuthJSON() }) + } + }) - if (req.body.user.password !== req.body.disable.password_verification) { - return res.status(api_code.error).json({ errors: { password: "verification mismatch" } }); - } - if (!req.body.disable.username_verification) { - return res.status(api_code.error).json({ errors: { username: "can't be blank" } }); - } + // delete an user + router.post('/users/delete', auth.required, async function (req: any, res) { + const user = await User.findById(req.payload.id) + if (!user) { + return res.sendStatus(apiCode.forbidden) + } + if (!user.authorized && !user.isAdmin()) { + return res.sendStatus(apiCode.forbidden) + } + if (user.processing) { + return res.sendStatus(apiCode.forbidden) + } - if (!user.isAdmin()) { - if (req.body.disable.username_verification !== user.username) { - return res.status(api_code.error).json({ errors: { username: "verification mismatch" } }); - } - } + if (!req.body.user.email) { + return res.status(apiCode.error) + .json({ errors: { email: "can't be blank" } }) + } - var authors = req.body.disable.username_verification; - - user.findAnUser(authors).then(function(results: any) { - - const author: any = results[0]; - - user.findAllServersOfAnUser(req.query, author, req.payload).then(function(results: any) { - var servers = results[0]; - if (servers.length == 0) { - author.active = !author.active; - console.log('user status up to date'); - author.save(); - if (!user.isAdmin()) { - return res.json({ user: author.toAuthJSON() }); - } - else { - return res.json({ user: user.toAuthJSON() }); - } - } - var itemsProcessed = 0; - - servers.forEach((server: any, index: any, array: any) => { - global_functions.asyncFunction(server, () => { - - if (server.active && user.active) { - console.log('preparing shut_off'); - var namespace = 'default'; - - server_functions.removekubelink(server.slug, namespace).then((response: any) => { - server.active = false; - server.save(); - - }, (err: any) => { - // return res.status(api_code.error).send({ errors: { err } }); - console.log(err); - }); - } - - itemsProcessed++; - if (itemsProcessed === array.length) { - - // add a waiting list (interval) for all servers - - console.log('author = ' + author); - console.log('all servers are done'); - author.active = !author.active; - console.log('user status up to date'); - author.save(); - if (!user.isAdmin()) { - return res.json({ user: author.toAuthJSON() }); - } - else { - return res.json({ user: user.toAuthJSON() }); - } - } - }); - }); - }); - }).catch(next); - }).catch(next); - }); - - //delete an user - router.post('/users/delete', auth.required, function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (!user) { return res.sendStatus(api_code.forbidden); } - if (!user.authorized && !user.isAdmin()) { return res.sendStatus(api_code.forbidden); } - if (user.processing) { return res.sendStatus(api_code.forbidden); } - - if (!req.body.user.email) { - return res.status(api_code.error).json({ errors: { email: "can't be blank" } }); - } + if (req.body.user.email !== user.email) { + return res.status(apiCode.error) + .json({ errors: { email: 'does not correspond' } }) + } - if (req.body.user.email !== user.email) { - return res.status(api_code.error).json({ errors: { email: "does not correspond" } }); - } + if (!req.body.user.password) { + return res.status(apiCode.error) + .json({ errors: { password: "can't be blank" } }) + } - if (!req.body.user.password) { - return res.status(api_code.error).json({ errors: { password: "can't be blank" } }); - } + if (!user.validPassword(req.body.user.password)) { + return res.status(apiCode.error) + .json({ errors: { password: 'does not correspond' } }) + } + if (!req.body.disable.username_verification) { + return res.status(apiCode.error) + .json({ errors: { username: "can't be blank" } }) + } + if (!user.isAdmin() && + req.body.disable.username_verification !== user.username) { + return res.status(apiCode.error) + .json({ errors: { username: 'verification mismatch' } }) + } - if (!user.validPassword(req.body.user.password)) { - return res.status(api_code.error).json({ errors: { password: "does not correspond" } }); - } + const [author] = + await user.findAnUser(req.body.disable.username_verification) + console.log('author = ' + author) + + const [servers] = + await user.findAllServersOfAnUser(req.query, author, req.payload) + const namespace = 'default' + + await Promise.all(servers.map(async (server: any) => { + console.log(`asking for a deletion: ${server.slug}`) + await server_functions.removekubelink(server.slug, namespace) + console.log('kubelink removed') + + await cloud.deleteObjects(server.slug) + console.log('swift container removed') + + const serverDir = + path.join('./uploads', user.username, server.slug) + await fs.promises.rm(serverDir, { recursive: true }) + console.log('server deleted from uploads') + + return server.remove() + })) + + console.log('all servers are done') + await author.remove() + return res.sendStatus(apiCode.ok) + }) + + router.post('/users', async function (req: any, res) { + const user = new User() + + user.username = req.body.user.username + user.email = req.body.user.email + user.description = req.body.user.description + user.place = req.body.user.place + user.goal = req.body.user.goal + user.setPassword(req.body.user.password) + + await user.save() + return res.json({ user: user.toAuthJSON() }) + }) + + router.post('/user/activate', auth.required, async function (req: any, res) { + const user = await User.findById(req.payload.id) + if (!user) { + return res.sendStatus(apiCode.forbidden) + } + if (!user.isAdmin()) { + return res.sendStatus(apiCode.forbidden) + } - if (!req.body.disable.password_verification) { - return res.status(api_code.error).json({ errors: { password: "can't be blank" } }); - } + const [userToActivate] = await user.findAnUser(req.body.user.username) + userToActivate.authorized = true + userToActivate.active = true + await userToActivate.save() + return res.json({ user: userToActivate.toAuthJSON() }) + }) + + router.post('/user/authorize', auth.required, async function (req: any, res) { + const user = await User.findById(req.payload.id) + if (!user) { + return res.sendStatus(apiCode.forbidden) + } + if (!user.isAdmin()) { + return res.sendStatus(apiCode.forbidden) + } - if (req.body.user.password !== req.body.disable.password_verification) { - return res.status(api_code.error).json({ errors: { password: "verification mismatch" } }); - } - if (!req.body.disable.username_verification) { - return res.status(api_code.error).json({ errors: { username: "can't be blank" } }); - } - if (!user.isAdmin()) { - if (req.body.disable.username_verification !== user.username) { - return res.status(api_code.error).json({ errors: { username: "verification mismatch" } }); - } - } + const [userToAuthorize] = await user.findAnUser(req.body.user.username) + userToAuthorize.authorized = true + userToAuthorize.processing = false - var authors = req.body.disable.username_verification; - console.log('author = ' + authors); - user.findAnUser(authors).then(function(results: any) { - - const author: any = results[0]; - console.log('author = ' + author); - user.findAllServersOfAnUser(req.query, author, req.payload).then(function(results: any) { - var servers = results[0]; - if (servers.length == 0) { - author.remove(); - return res.sendStatus(api_code.ok); - } - console.log('author = ' + author); - var namespace = 'default'; - var itemsProcessed = 0; - var itemToDelete = servers.length; - servers.forEach((server: any, _index: any, array: any) => { - global_functions.asyncFunction(server, async () => { - console.log('asking for a deletion'); - console.log('slug : ' + server.slug); - console.log('namespace : ' + namespace); - - await server_functions.removekubelink(server.slug, namespace) - console.log('kubelink removed') - - await cloud.deleteObjects(server.slug) - console.log('swift container removed') - - const serverDir = - path.join('./uploads', user.username, server.slug) - await upload_functions.removeDir(serverDir) - console.log('server deleted') - - itemToDelete--; - server.remove(); - }); - itemsProcessed++; - if (itemsProcessed === array.length) { - var userInChange = setInterval(function() { - if (itemToDelete === 0) { - clearInterval(userInChange); - console.log('all servers are done'); - author.remove(); - return res.sendStatus(api_code.ok); - } - console.log('itemToDelete : ' + itemToDelete); - }, 5000); - // add a waiting list (interval) for all servers - - - } - }); - }); - }).catch(next); - }).catch(next); - }); - - router.post('/users', function(req: any, res, next) { - var user = new User(); - - user.username = req.body.user.username; - user.email = req.body.user.email; - user.description = req.body.user.description; - user.place = req.body.user.place; - user.goal = req.body.user.goal; - user.setPassword(req.body.user.password); - - // var namespace = user_functions.createObjectNamespace('default'); - - // user_functions.createNamespace(namespace).then((response) => { - // user_functions.readNamespace(namespace.metadata.name); - - // }); - - - user.save().then(function() { - return res.json({ user: user.toAuthJSON() }); - }).catch(next); - }); - - router.post('/user/activate', auth.required, function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (!user) { return res.sendStatus(api_code.forbidden); } - if (!user.isAdmin()) { return res.sendStatus(api_code.forbidden); } - user.findAnUser(req.body.user.username).then(function(userToActivate: any) { - userToActivate[0].authorized = true; - userToActivate[0].active = true; - userToActivate[0].save().then(function() { - return res.json({ user: userToActivate[0].toAuthJSON() }); - }).catch(next); - }).catch(next); - }).catch(next); - }); - - router.post('/user/authorize', auth.required, function(req: any, res, next) { - User.findById(req.payload.id).then(function(user: any) { - if (!user) { return res.sendStatus(api_code.forbidden); } - if (!user.isAdmin()) { return res.sendStatus(api_code.forbidden); } - user.findAnUser(req.body.user.username).then(function(userToActivate: any) { - userToActivate[0].authorized = true; - userToActivate[0].processing = false; - userToActivate[0].save().then(function() { - return res.json({ user: userToActivate[0].toAuthJSON() }); - }).catch(next); - }).catch(next); - }).catch(next); - }); + await userToAuthorize.save() + return res.json({ user: userToAuthorize.toAuthJSON() }) + }) return router } diff --git a/BackEnd/src/lib/errors.ts b/BackEnd/src/lib/errors.ts deleted file mode 100644 index e5d8278..0000000 --- a/BackEnd/src/lib/errors.ts +++ /dev/null @@ -1,58 +0,0 @@ -export default { - - wget_error: function (code : number) { - var message = ''; - switch (code) { - case 4: - message = 'Network Failure' - break; - case 5: - message = 'SSL verification failure.' - break; - case 7: - message = 'Protocol errors.' - break; - case 8: - message = 'Server issued an error response.' - break; - default: - message = 'Error unknown.' - break; - } - return message; - }, - - group_duplicate: function (files : any) { - for (let i = 0; i < files.length - 1; i++) { - for (let j = i + 1; j < files.length; j++) { - if (files[i][0] === files[j][0]) { - return true; - } else { - console.log('not found : ' + files[i][0] + ' ' + files[j][0]); - if (i === files.length - 1) { - return false; - } - } - } - } - - }, - - wrap_error: function (fun : any, status : any, err : any) { - if (err.fun === undefined) { - throw { fun, status, err }; - } else { - throw err; - } - }, - - unwrap_error: function (res : any, err : any) { - if (err.fun !== undefined) { - console.log('Error ' + err.fun + ': '); - console.log(err.err); - res.status(err.status).json({ errors: { errors: err.err.message } }); - } else { - throw err; - } - } -}; diff --git a/BackEnd/src/lib/upload_functions.ts b/BackEnd/src/lib/upload_functions.ts deleted file mode 100644 index 19b21ff..0000000 --- a/BackEnd/src/lib/upload_functions.ts +++ /dev/null @@ -1,670 +0,0 @@ -const fs = require('fs'); -const fsDir = require('fs-extra'); -const unzipper = require('unzipper'); -const url = require('url'); -const child_process = require('child_process'); -const rimraf = require("rimraf"); -const global_functions = require('./global_functions'); -const saveFile = 'index_saved.txt' -const separator = '®'; -const new_separator = ''; -const repository = 'repository/'; -const sync = 'sync/'; -const archiver = require('archiver'); -const util = require('util'); - -const path = require('path'); -const fsPromises = fs.promises; - -const defaultIndexJsonFilename = 'index.json'; -const defaultIndexJsonPath = '../configs/default_index.json'; -const groupPrefix = 'group-'; - -const defaultIndexObj = require(defaultIndexJsonPath); - -export const read = require('fs-readdir-recursive'); - -/** - * Workaround to convert a tabOfName (a dumb structure of matrix) - * the dumb structure is like [ [ "g1", "ex1", "ex2", ...], [ "g2", "ex3", ... ] ] - * to a standart list of groups - * a group has a structure like { title: "g1", exercises: ["ex1", "ex2", ...] } - */ -export function tabOfNameToGroups(tabOfName : string[][]) { - return tabOfName.map(group => { - return { title: group[0], exercises: group.slice(1) }; - }); -} - -/** - * Load a index.json file to extract the list of groups - * return a promise with the list of groups - * a group has a structure like { title: "g1", exercises: ["ex1", "ex2", ...] } - */ -export async function loadIndexJson(dirPath : string) { - const filePath = path.join(dirPath, defaultIndexJsonFilename); - - return fsPromises.readFile(filePath) - .then((buffer : string) => JSON.parse(buffer)) - .then((indexObject : any) => Object.values(indexObject.groups)); -} - -/** - * Save the index.json from a list of groups object - * a group has a structure like { title: "g1", exercises: ["ex1", "ex2", ...] } - */ -export async function saveIndexJson(dirPath : any, groups : any) { - const indexObject = JSON.parse(JSON.stringify(defaultIndexObj)); - const filePath = path.join(dirPath, defaultIndexJsonFilename); - - for (let i = 0; i < groups.length; i++) { - indexObject.groups[`${groupPrefix}${i}`] = groups[i]; - } - return Promise.resolve(JSON.stringify(indexObject, null, 4)) - .then(buffer => fsPromises.writeFile(filePath, buffer)); -} - -function create_IndexJSON_header() { - return new Promise(function (resolve, reject) { - return resolve('{ "learnocaml_version": "1",\n "groups":\n {\n'); - }); -} - -function create_IndexJSON_body(tabOfName : any) { - return new Promise(resolve => { - var body = ""; - for (let i = 0; i < tabOfName.length; i++) { - var group = tabOfName[i]; - for (let index = 0; index < group.length; index++) { - if (index === 0) { - body += ' "group-' + i + '":\n { "title": "' + group[index] + '",\n "exercises": [\n'; - - } else if (index === group.length - 1) { - body += ' "' + group[index] + '" ] }'; - if (i !== tabOfName.length - 1) { - body += ',\n'; - } - else { - body += '\n'; - if (i === tabOfName.length - 1) { - return resolve(body); - } - } - } - else { - body += ' "' + group[index] + '",\n'; - } - } - }; - }); -} - -function create_IndexJSON_footer() { - return new Promise(resolve => { - return resolve('} }'); - }); -} - -function addFileInTabOfName(element : any, tmp : any) { - return new Promise(resolve => { - var new_group = []; - for (let i = 0; i < element.length; i++) { - if (i === 0) { - new_group.push(element[i].replace(separator, new_separator)); - } - else { - if (tmp.includes(element[i])) { - //console.log(tmp + ' contains : ' + element[i] + ' so it will be push in ' + new_group); - new_group.push(element[i].replace(separator, new_separator)); - //console.log('new_group : ' + new_group); - } - if (i == element.length - 1) { - //console.log('finally new_group : ' + new_group); - return resolve(new_group); - } - } - } - }); -} - -function file_to_delete(path : string, element : any, - useless : any, tabOfName : any) { - return new Promise(function (resolve, reject) { - fs.stat(path + element, function (err : any, stat : any) { - if (err) return reject(err); - if (stat.isFile()) { - console.log(path + element + ' is a file, so it will be deleted'); - fs.unlink(path + element, function (err : any) { - if (err) return reject(err); - return resolve(undefined); - }); - } - else if (stat.isDirectory()) { - if (!fs.readdirSync(path + element).includes('meta.json')) { - console.log(path + element + ' don t contain meta.json file, so it will be deleted'); - return resolve(path + element); - - } - else if (useless.includes(element)) { - console.log(path + element + ' is included in useless file, so it will be deleted'); - return resolve(path + element); - - } - else { - var found = false; - for (let i = 0; i < tabOfName.length; i++) { - const group = tabOfName[i]; - if (group.includes(element)) { - console.log(path + element + ' is included in tabOfName file, possess an meta.json file and is not included in useless file, so it will be kept'); - return resolve(undefined); - } - else { - if (i === tabOfName.length - 1) { - console.log('tabOfName : ' + tabOfName); - console.log('group : ' + group); - console.log('element : ' + element); - console.log('tabOfName doesnt contains element : ' + element + ' in group ' + group); - console.log(path + element + ' is not included in tabOfName file, so it will be deleted'); - return resolve(path + element); - } - } - } - } - } - else { - return reject('Unknown format'); - } - }); - }); -} - -function deleteDir(tab_of_dir : any) { - return new Promise(function (resolve, reject) { - var tmp = tab_of_dir.length; - console.log('tmp.length : ' + tmp); - if (tmp === 0) { - console.log('no more file to delete'); - return resolve(undefined); - } - for (let i = 0; i < tab_of_dir.length; i++) { - rimraf(tab_of_dir[i], function (err : any) { - if (err) return reject(err); - console.log('file deleted in tmp'); - tmp--; - console.log('tmp.length : ' + tmp); - if (tmp === 0) { - console.log('no more file to delete'); - return resolve(undefined); - } - }) - } - }); -} -/** - * - * @param {*} source - * @param {*} dest - * @param {*} format - * @param {*} archive_name - */ -export async function createArchiveFromDirectory(source : string, dest : string, - format : any, archive_name : any) { - var files = read(source) - .map((file : string) => - [path.join(source, file), path.join(dest, file)]); - if (files === []) { - throw 'empty files list'; - } - await createArchive(files, format, archive_name); -} - -/** - * Create an archive from list of files - * files : list of pairs of [path_to_file, archive_path_of_file] - * (ex: ['dir1/file1', 'dir2/dir3/file1']) - * format : format of compression (ex: 'zip') - * archive_name : the name of the archive - */ -export async function createArchive(files : any, format : any, - archive_name = 'archive') { - const stream = fs.createWriteStream(archive_name + '.' + format); - const archive = archiver(format, {}); - - await new Promise(resolve => { - stream.on('close', function () { - console.log('archive ' + archive + ' created'); - resolve(undefined); - }); - - archive.pipe(stream); - files.forEach((file : any) => { - archive.file(file[0], { name: file[1] }); - }); - archive.finalize(); - }); -} - -export function desarchived(dest_path : any, source_path : any) { - return new Promise(function (resolve, reject) { - - fs.createReadStream(source_path).pipe(unzipper.Extract({ path: dest_path })) - .on('close', function (err : any) { - if (err) return reject(err); - return resolve(dest_path); - }) - .on('error', function (err : any) { - return reject(err); - }); - }); -} - -export function checkFiles(path : string) { - return new Promise(function (resolve, reject) { - if (fs.existsSync(path)) { - fs.readdir(path, function (err : any, files : any) { - if (err) return reject(err); - else if (!files.length) { - return resolve([]); - } - else return resolve(files); - }) - } else { - return resolve([]); - } - }); -} - -export function fileExists(path : string) { - return Promise.resolve(fs.existsSync(path)); -} - -export function unlinkSync(path : string) { - return new Promise(function (resolve, reject) { - if (fs.existsSync(path)) { - fs.unlink(path, function (err : any) { - if (err) return reject(err); - return resolve('deleted'); - }) - } else { - return resolve('deleted'); - } - }); -} - -export function copyFile(source : any, dest : any) { - return new Promise(function (resolve, reject) { - if (fs.existsSync(source)) { - fs.copyFile(source, dest, (err : any) => { - if (err) return reject(err); - console.log(source + 'was copied to ' + dest); - return resolve(undefined); - }); - } else { - return reject('Source file doesnt exist'); - } - }) -} - -export function download_from_url(file_url : any, dest_path : any) { - return new Promise(function (resolve, reject) { - - var file_name = url.parse(file_url).pathname.split('/').pop(); - var wget = 'wget -P ' + dest_path + ' ' + file_url; - - child_process.exec(wget, (err : any) => { - if (err) return reject(err); - return resolve(dest_path + file_name); - }); - }); -} - -export function delete_useless_files(useless : any, path : any, - tabOfName : any, files : any) { - return new Promise(function (resolve, reject) { - if (useless === [] || useless === undefined || useless === null) { - return resolve('nothing to delete'); - } - //console.log('tabOfName before filter : ' + tabOfName); - tabOfName = tabOfName.filter((group : any) => group.length >= 2); - //console.log('tabOfName after filter : ' + tabOfName); - - var tmp : any = []; - var itemsProcessed = 0; - files.forEach((element : any, index : any, array : any) => { - global_functions.asyncFunction(element, () => { - file_to_delete(path, element, useless, tabOfName) - .then((response) => { - if (response) { - console.log(response + ' added in tmp'); - tmp.push(response); - } - itemsProcessed++; - if (itemsProcessed === array.length) { - console.log('tmp : ' + tmp); - deleteDir(tmp).then((response) => { - console.log('all file deleted'); - if (!tabOfName.length) { - return reject('No file available'); - } else { - return resolve(tabOfName); - } - }) - } - }, (err) => { - console.log('Error file_to_delete !: ' + err); - return reject(err); - }); - }); - }); - }); -} - -export function create_new_tabOfName(save_path : any, path : any, tabOfName : any) { - return new Promise(function (resolve, reject) { - - var nameProcessed = 0; - var tmp = fs.readdirSync(path); - var new_tabOfName : any = [[]]; - - tabOfName.forEach((element : any, index : any, array : any) => { - global_functions.asyncFunction(element, () => { - addFileInTabOfName(element, tmp).then(async (response) => { - if (response) { - //console.log('new group in new_tab_of_name : ' + response); - new_tabOfName.push(response); - //console.log('new_tab_of_name : ' + new_tabOfName); - } - nameProcessed++; - if (nameProcessed === array.length) { - //console.log('new_tabOfName before filter : ' + new_tabOfName); - new_tabOfName = new_tabOfName.filter((group : any) => group.length >= 2); - //console.log('new_tabOfName after filter : ' + new_tabOfName); - if (!new_tabOfName.length) { - return reject(': No correct files found for index.json'); - } - else { - var groups = tabOfNameToGroups(new_tabOfName); - await saveIndexJson(save_path, groups); - resolve(new_tabOfName); - } - } - }, - (err) => { - console.log('Error file_to_delete !: ' + err); - return reject(err); - }); - }); - }); - }); -} - -function _save_tabOfName(save_path : any, tabOfName : any) { - return new Promise(function (resolve, reject) { - var line = ''; - tabOfName.forEach((tab : any) => { - tab.forEach((element : any) => { - line += element + separator; - }); - line += '\n'; - }); - fs.writeFile(save_path + saveFile, line, function (err : any) { - if (err) { - console.log('error in saving tabofname'); - return reject(err); - } - console.log('index_saved created'); - return resolve('ok'); - }) - }) -} - -export function load_tabOfName(save_path : any) { - return new Promise(function (resolve, reject) { - fs.readFile(save_path + saveFile, 'utf8', (err : any, data : any) => { - if (err) { - if (err.code === 'ENOENT') { - console.error('The save file doesnt exist now, it is the first time the repository is created'); - return resolve([]); - } else { - return resolve([]); - console.log(err); - return reject(err); - } - } else { - var res = [] - var data_ = data.split('\n'); - for (let index = 0; index < data_.length - 1; index++) { - const element = data_[index]; - var items = element.split(separator); - var exercises_ = []; - for (let index = 1; index < items.length - 1; index++) { - exercises_.push(items[index]); - } - var group = { - title: items[0], - exercises: exercises_ - } - res.push(group); - } - return resolve(res); - } - }) - }) -} - -export function create_indexJSON(path : any, tabOfName : any) { - return new Promise(function (resolve, reject) { - create_IndexJSON_header().then((header : any) => { - //console.log('header created : \n' + header); - create_IndexJSON_body(tabOfName).then((body : any) => { - //console.log('body created : \n' + body); - create_IndexJSON_footer().then((footer : any) => { - //console.log('footer created : \n' + footer); - fs.writeFile(path, header + body + footer, (err : any) => { - if (err) return reject(err); - console.log('index.json : ' + header + body + footer); - return resolve(path + 'exercises/index.json'); - }); - }) - }) - }) - }); -} - -export function removeDir(path : any) { - return new Promise(function (resolve, reject) { - if (fs.existsSync(path)) { - rimraf(path, function (err : any) { - if (err) return reject(err); - return resolve('removed'); - }); - } - else { return resolve('removed'); } - }); -} - -export function renameDir(oldPath : any, newPath : any, - unknown : any, remove_if_not_empty : any) { - return new Promise(function (resolve, reject) { - if (unknown) { - fs.readdir(oldPath, function (err : any, files : any) { - if (err) return reject(err); - else { - fs.rename(oldPath + files[0], newPath, (err : any) => { - if (err) return reject(err); - return resolve('renamed'); - }) - } - }) - } else { - fs.rename(oldPath, newPath, function (err : any) { - if (err) { - return reject(err); - } - return resolve('renamed'); - }) - } - - }) -} - -export function createDir(path : any) { - return new Promise(function (resolve, reject) { - fs.mkdir(path, function (err : any) { - if (err) { - if (err.code === 'EEXIST') { - console.error('my repository already exists at ' + path); - } else { - return reject(err); - } - } - return resolve('ok'); - }); - }); -} - -export function createArbo(path : any, server_name : any, - safe_folder : any, dirt_folder : any, save_folder : any, - download_folder : any) { - return new Promise(function (resolve, reject) { - createDir(path).then(() => { - createDir(path + server_name).then(() => { - createDir(path + server_name + safe_folder).then(() => { - createDir(path + server_name + dirt_folder).then(() => { - createDir(path + server_name + save_folder).then(() => { - createDir(path + server_name + download_folder).then(() => { - return resolve('done'); - }, (err) => { - console.log('Error creating download_folder !: ' + err); - return reject(err); - }); - }, (err) => { - console.log('Error creating save_folder !: ' + err); - return reject(err); - }); - }, (err) => { - console.log('Error creating dirt_folder !: ' + err); - return reject(err); - }); - }, (err) => { - console.log('Error creating safe_folder !: ' + err); - return reject(err); - }); - }, (err) => { - console.log('Error creating path + server name folder !: ' + err); - return reject(err); - }); - }, (err) => { - console.log('Error creating path_folder !: ' + err); - return reject(err); - }); - - }); -} - -export function copyDir(source : any, destination : any) { - return new Promise(function (resolve, reject) { - fsDir.copy(source, destination, (err : any) => { - if (err) { - console.log('An error occured while copying the folder.') - return reject(err); - } - console.log(source + ' folder has been succefully copied in ' + destination); - return resolve("ok"); - }); - }) -} - -export function moveDir(source : any, destination : any) { - return new Promise(function (resolve, reject) { - fsDir.move(source, destination, function (err : any) { - if (err) { - console.log('An error occured while moving the folder.') - return reject(err); - } - console.log(source + ' folder has been succefully moved in ' + destination); - return resolve("ok"); - }); - }) - -} - -export function archive_traitement(dest_path : any, source_path : any, - archive_folder : any, safe_folder : any, - link_github = '') { - return new Promise(function (resolve, reject) { - desarchived(dest_path + archive_folder, source_path).then((response) => { - console.log('desachived done'); - checkFiles(dest_path + archive_folder).then((archive_name : any) => { - console.log('check done'); - copyDir(dest_path + archive_folder + archive_name[0] + link_github, dest_path + safe_folder) - .then((response : any) => { - console.log('copyDir done'); - removeDir(dest_path + archive_folder).then(() => { - console.log('removeDir done'); - unlinkSync(source_path).then((response) => { - console.log('unlink done'); - checkFiles(dest_path + safe_folder).then((files) => { - console.log('checkFiles done'); - console.log('archive traitement done'); - return resolve(files); - }, (err) => { - console.log('Error checkFiles !: ' + err); - return reject(err); - }); - }, (err) => { - console.log('Error unlink !: ' + err); - return reject(err); - }); - }, (err) => { - console.log('Error removeDir !: ' + err); - return reject(err); - }); - }, (err) => { - console.log('Error copydir !: ' + err); - return reject(err); - }); - }, (err) => { - console.log('Error checkFiles !: ' + err); - return reject(err); - }); - }, (err) => { - console.log('Error desarchived !: ' + err); - return reject(err); - }); - }); -} - -export function parse_url(file_url : any) { - return url.parse(file_url).host; -} - -/* -var upload_functions = { - unlinkSync: unlinkSync, - download_from_url: download_from_url, - delete_useless_files: delete_useless_files, - create_new_tabOfName: create_new_tabOfName, - create_indexJSON: create_indexJSON, - createArchive, - createArchiveFromDirectory, - removeDir: removeDir, - renameDir: renameDir, - createArbo: createArbo, - copyFile: copyFile, - copyDir: copyDir, - moveDir: moveDir, - fileExists: fileExists, - load_tabOfName: load_tabOfName, - archive_traitement: archive_traitement, - createDir: createDir, - parse_url: function (file_url : any) { - return url.parse(file_url).host; - }, - saveIndexJson, - loadIndexJson, - tabOfNameToGroups, -}; - -module.exports = upload_functions; -*/ diff --git a/BackEnd/src/middlewares/index.ts b/BackEnd/src/middlewares/index.ts index f615b4c..a8e4ef1 100644 --- a/BackEnd/src/middlewares/index.ts +++ b/BackEnd/src/middlewares/index.ts @@ -1,23 +1,28 @@ import { cors, json, urlencoded } from './core' -import { devError } from './errorhandlers' +import { devError, prodError } from './errorhandlers' import { morgan } from './logging' import { helmet } from './security' -import { session } from './session' const middlesAll = { cors, json, morgan, - session, urlencoded } export const middlesDev = { - ...middlesAll, - devError + ...middlesAll } export const middlesProd = { ...middlesAll, helmet } + +export const errorsDev = { + devError +} + +export const errorsProd = { + prodError +} diff --git a/BackEnd/src/middlewares/session.ts b/BackEnd/src/middlewares/session.ts deleted file mode 100644 index ec2e1d2..0000000 --- a/BackEnd/src/middlewares/session.ts +++ /dev/null @@ -1,8 +0,0 @@ -import sess from 'express-session' - -export const session = () => sess({ - secret: 'essok', - cookie: { maxAge: 60000 }, - resave: false, - saveUninitialized: false -}) diff --git a/FrontEnd/package-lock.json b/FrontEnd/package-lock.json index c209e08..6a69a76 100644 --- a/FrontEnd/package-lock.json +++ b/FrontEnd/package-lock.json @@ -807,7 +807,6 @@ "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-11.0.3.tgz", "integrity": "sha512-hgbJXvZURKBnZawwxUrsZE/3a+HCJh2UhoLIng3cn5Q+WIW/4a37knDl8B9DYKBWrCqeINXNcUHVSKkWc/gjCA==", "dependencies": { - "parse5": "^5.0.0", "tslib": "^2.0.0" }, "optionalDependencies": { @@ -1059,6 +1058,7 @@ "version": "11.0.3", "resolved": "https://registry.npmjs.org/@angular/material/-/material-11.0.3.tgz", "integrity": "sha512-YTHmtKGwjAEFAOOmuivcwnINMPHxvM7iZQpTgZqDKNiqiv53cwry2Ctb54suRNT+D794z59D0/r+YocGkzFv3w==", + "dev": true, "dependencies": { "tslib": "^2.0.0" }, @@ -4036,7 +4036,6 @@ "dependencies": { "anymatch": "~3.1.1", "braces": "~3.0.2", - "fsevents": "~2.3.1", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", @@ -8499,9 +8498,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dependencies": { - "graceful-fs": "^4.1.6" - }, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -8829,13 +8825,6 @@ "integrity": "sha512-+1V2PCMFkL+OIj2/HrtrvZw0BC0sYLMICJfbQjuj/K8CEnlrFX6R5cKKgzzttsZDHyxQNL1jqMREjKN3ja/E3Q==", "dev": true, "dependencies": { - "errno": "^0.1.1", - "graceful-fs": "^4.1.2", - "image-size": "~0.5.0", - "make-dir": "^2.1.0", - "mime": "^1.4.1", - "native-request": "^1.0.5", - "source-map": "~0.6.0", "tslib": "^1.10.0" }, "bin": { @@ -12928,9 +12917,6 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.32.1.tgz", "integrity": "sha512-Op2vWTpvK7t6/Qnm1TTh7VjEZZkN8RWgf0DHbkKzQBwNf748YhXbozHVefqpPp/Fuyk/PQPAnYsBxAEtlMvpUw==", "dev": true, - "dependencies": { - "fsevents": "~2.1.2" - }, "bin": { "rollup": "dist/bin/rollup" }, @@ -15469,10 +15455,8 @@ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", "dependencies": { - "chokidar": "^3.4.1", "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.1" + "neo-async": "^2.5.0" }, "optionalDependencies": { "chokidar": "^3.4.1", @@ -15562,7 +15546,6 @@ "anymatch": "^2.0.0", "async-each": "^1.0.1", "braces": "^2.3.2", - "fsevents": "^1.2.7", "glob-parent": "^3.1.0", "inherits": "^2.0.3", "is-binary-path": "^1.0.0", @@ -16103,7 +16086,6 @@ "anymatch": "^2.0.0", "async-each": "^1.0.1", "braces": "^2.3.2", - "fsevents": "^1.2.7", "glob-parent": "^3.1.0", "inherits": "^2.0.3", "is-binary-path": "^1.0.0", @@ -18258,6 +18240,7 @@ "version": "11.0.3", "resolved": "https://registry.npmjs.org/@angular/material/-/material-11.0.3.tgz", "integrity": "sha512-YTHmtKGwjAEFAOOmuivcwnINMPHxvM7iZQpTgZqDKNiqiv53cwry2Ctb54suRNT+D794z59D0/r+YocGkzFv3w==", + "dev": true, "requires": { "tslib": "^2.0.0" } diff --git a/FrontEnd/src/app/core/services/servers.service.ts b/FrontEnd/src/app/core/services/servers.service.ts index 4478612..89ba936 100644 --- a/FrontEnd/src/app/core/services/servers.service.ts +++ b/FrontEnd/src/app/core/services/servers.service.ts @@ -62,11 +62,13 @@ export class ServersService { .pipe(map(data => data)); } - send(slug : string, useless: string[], list : string[][], trash : string[]) { + send(slug : string, useless: string[], + groups : { [id: string]: { title: string, exercises: string[] } }, + trash : string[]) { return this.apiService.post('/uploads/send', { server: slug, useless, - list, + groups, trash, }); } diff --git a/FrontEnd/src/app/server-settings/server-settings.component.ts b/FrontEnd/src/app/server-settings/server-settings.component.ts index b61eaf5..9f1f29b 100644 --- a/FrontEnd/src/app/server-settings/server-settings.component.ts +++ b/FrontEnd/src/app/server-settings/server-settings.component.ts @@ -47,7 +47,6 @@ export class ServerSettingsComponent implements OnInit { exercisesDropList: string[] = []; trashDropList: string[] = []; groupsList: Group[] = []; - useless: ExercisesList = {} as ExercisesList; IMGPANELS = IMGPANELS; uploadHeaders: string[] = ['name', 'size', 'status']; dangerousZonePanelState: boolean = false; @@ -90,7 +89,6 @@ export class ServerSettingsComponent implements OnInit { updateExercisesDropList() { this.exercisesDropList = ['trash-list', 'exercises-list', 'create-group-list', ...this.groupsList.map(group => group.id)]; - console.log(this.exercisesDropList); } generateGroupID() { @@ -119,28 +117,23 @@ export class ServerSettingsComponent implements OnInit { loadGroups() { this.serversService .getGroups(this.server.slug) - .subscribe( - data => { - this.useless = JSON.parse(JSON.stringify(data)); - this.groupsList = this.useless.group.map( - group => { return { ...group, id: this.generateGroupID() }; }); - this.updateExercisesDropList() - this.exercisesList = this.useless.name; - this.trashList = []; - this.errors = {}; - }, - err => { - this.errors = err; - } - ) + .subscribe(data => { + const groups = + data.groups as { [id: string]: { title: string, exercises: string[] }} + this.groupsList = Object.entries(groups) + .map(([id, group]) => ({ id, ...group })) + this.updateExercisesDropList() + this.exercisesList = data.exercisesList; + this.trashList = []; + this.errors = {}; + }, err => { this.errors = err }) } uploadPrepare() { this.uploader.onAfterAddingFile = (file) => { file.withCredentials = false; }; - this.uploader.onCompleteItem = (item: any, response: any, status: any, headers: any) => { - console.log('FileUpload:uploaded:', item, status, response); - this.useless = JSON.parse(response); - this.exercisesList = this.useless.name; + this.uploader.onCompleteItem = (item: any, res: any, status: any, headers: any) => { + console.log('FileUpload:uploaded:', item, status, res); + this.exercisesList = res.name; this.trashList = []; this.loadGroups(); // move to the next slide @@ -173,8 +166,7 @@ export class ServerSettingsComponent implements OnInit { this.serversService.uploadFromUrl(this.server.slug, this.serverSettingsForm.value).subscribe( data => { - this.useless = JSON.parse(JSON.stringify(data)); - this.exercisesList = this.useless.name; + this.exercisesList = data.name; this.loadGroups(); }, err => { @@ -189,8 +181,7 @@ export class ServerSettingsComponent implements OnInit { this.serversService.uploadFromUrl(this.server.slug, this.serverSettingsForm.value).subscribe( data => { - this.useless = JSON.parse(JSON.stringify(data)); - this.exercisesList = this.useless.name; + this.exercisesList = data.name; this.loadGroups(); }, err => { @@ -232,16 +223,11 @@ export class ServerSettingsComponent implements OnInit { } send() { - var groups = [[]]; - this.modalService.open('pleaseWait2'); - // TODO: remove the horrible matrix structure - this.groupsList.forEach(element => { - groups.push([element.title].concat(element.exercises)); - }); + let groups = this.groupsList + .reduce((acc, { id, ...group }) => ({ ...acc, [id]: group }), {}) this.serversService.send(this.server.slug, this.exercisesList, groups, this.trashList) .subscribe(_res => { - this.modalService.close('pleaseWait2'); this.isDisabled = false; this.loadGroups(); let that = this; @@ -252,7 +238,6 @@ export class ServerSettingsComponent implements OnInit { }) }, err => { - this.modalService.close('pleaseWait2'); this.errors = err; this.isSubmitting = false; } From 2ff31727dd307a366a3bdf13ba9332862e04e82b Mon Sep 17 00:00:00 2001 From: Astyax NOUREL Date: Tue, 22 Mar 2022 14:04:33 +0100 Subject: [PATCH 3/6] fix user deletion does not purge jwt if user is self deleting as admin fix most of express response sendStatus call followed by json --- BackEnd/.eslintignore | 6 +-- BackEnd/package-lock.json | 12 ++--- BackEnd/src/controllers/profiles.ts | 2 +- BackEnd/src/controllers/server.ts | 41 ++++++++-------- BackEnd/src/controllers/upload.ts | 48 +++++++++---------- BackEnd/src/controllers/users.ts | 25 +++++----- .../delete-account.component.ts | 4 +- 7 files changed, 70 insertions(+), 68 deletions(-) diff --git a/BackEnd/.eslintignore b/BackEnd/.eslintignore index d8781b2..7febe56 100644 --- a/BackEnd/.eslintignore +++ b/BackEnd/.eslintignore @@ -5,7 +5,7 @@ src/configs/**/*.ts src/lib/**/*.ts src/models/*.ts src/controllers/auth.ts -#src/controllers/users.ts -#src/controllers/profiles.ts -#src/controllers/server.ts +src/controllers/users.ts +src/controllers/profiles.ts +src/controllers/server.ts #src/controllers/upload.ts diff --git a/BackEnd/package-lock.json b/BackEnd/package-lock.json index 7383339..9d64a39 100644 --- a/BackEnd/package-lock.json +++ b/BackEnd/package-lock.json @@ -4301,9 +4301,9 @@ } }, "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "node_modules/minipass": { "version": "3.1.3", @@ -10300,9 +10300,9 @@ } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "minipass": { "version": "3.1.3", diff --git a/BackEnd/src/controllers/profiles.ts b/BackEnd/src/controllers/profiles.ts index 6e05236..38bcfc6 100644 --- a/BackEnd/src/controllers/profiles.ts +++ b/BackEnd/src/controllers/profiles.ts @@ -14,7 +14,7 @@ const router = Router() router.param('username', async function (req: any, res, next, username) { const user = await User.findOne({ username: username }) if (!user) { - return res.sendStatus(apiCode.not_found) + return res.status(apiCode.not_found) .json({ errors: { errors: 'User not found' } }) } req.profile = user diff --git a/BackEnd/src/controllers/server.ts b/BackEnd/src/controllers/server.ts index 421c5fd..7e263d8 100644 --- a/BackEnd/src/controllers/server.ts +++ b/BackEnd/src/controllers/server.ts @@ -25,7 +25,7 @@ export function serverAPI (cloud: CloudService) { router.param('server', async function (req: any, res, next, slug) { const server = await Server.findOne({ slug: slug }).populate('author') if (!server) { - return res.sendStatus(apiCode.not_found) + return res.status(apiCode.not_found) .json({ errors: { errors: 'Server ' + slug + ' not found' } }) } req.server = server @@ -34,24 +34,25 @@ export function serverAPI (cloud: CloudService) { router.get('/', auth.required, async function (req: any, res) { const user = await User.findById(req.payload.id) + debugger if (!user) { log_functions.create('error', 'get /server/', log_message.user_account_unknown + user, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.isAdmin() && !user.authorized) { log_functions.create('error', 'get /server/', log_message.user_activated_error, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if ((user.username !== req.query.author) && !user.isAdmin()) { log_functions.create('error', 'get /server/', log_message.user_owner_error, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } @@ -72,19 +73,19 @@ export function serverAPI (cloud: CloudService) { log_functions.create('error', 'post /server/', log_message.user_account_unknown + user, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.active) { log_functions.create('error', 'post /server/', log_message.user_account_error, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.isAdmin() && !user.authorized) { log_functions.create('error', 'post /server/', log_message.user_activated_error, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } @@ -109,13 +110,13 @@ export function serverAPI (cloud: CloudService) { log_functions.create('error', 'get /server/:' + req.server.slug, log_message.user_account_unknown + user, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.isAdmin() && !user.authorized) { log_functions.create('error', 'get /server/:' + req.server.slug, log_message.user_activated_error, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } @@ -123,7 +124,7 @@ export function serverAPI (cloud: CloudService) { if ((user.username !== server.author.username) && (!user.isAdmin())) { log_functions.create('error', 'get /server/:' + req.server.slug, log_message.user_account_error, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } @@ -138,13 +139,13 @@ export function serverAPI (cloud: CloudService) { if (!user.active) { log_functions.create('error', 'put /server/:' + req.server.slug, log_message.user_account_error, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.isAdmin() && !user.authorized) { log_functions.create('error', 'put /server/:' + req.server.slug, log_message.user_activated_error, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (user.processing) { @@ -188,13 +189,13 @@ export function serverAPI (cloud: CloudService) { if (!user.active) { log_functions.create('error', 'post /server/disable/:' + req.server.slug, log_message.user_account_error, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.isAdmin() && !user.authorized) { log_functions.create('error', 'post /server/disable/:' + req.server.slug, log_message.user_activated_error, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (user.processing) { @@ -256,19 +257,19 @@ export function serverAPI (cloud: CloudService) { log_functions.create('error', 'delete /server/:' + req.server.slug, log_message.user_account_unknown + user, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.active) { log_functions.create('error', 'delete /server/:' + req.server.slug, log_message.user_account_error, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.isAdmin() && !user.authorized) { log_functions.create('error', 'delete /server/:' + req.server.slug, log_message.user_activated_error, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (user.processing) { @@ -323,19 +324,19 @@ export function serverAPI (cloud: CloudService) { log_functions.create('error', 'post /server/:' + req.server.slug, log_message.user_account_unknown + user, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.active) { log_functions.create('error', 'post /server/:' + req.server.slug, log_message.user_account_error, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.isAdmin() && !user.authorized) { log_functions.create('error', 'post /server/:' + req.server.slug, log_message.user_activated_error, user, req.server) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (req.server.author._id.toString() !== req.payload.id.toString() && diff --git a/BackEnd/src/controllers/upload.ts b/BackEnd/src/controllers/upload.ts index ace6e1b..2d2af7b 100644 --- a/BackEnd/src/controllers/upload.ts +++ b/BackEnd/src/controllers/upload.ts @@ -50,7 +50,7 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { router.param('server', async (req, res, next, slug) => { const server = await Server.findOne({ slug: slug }).populate('author') if (!server) { - return res.sendStatus(apiCode.not_found) + return res.status(apiCode.not_found) .json({ errors: { errors: `Server ${slug} not found` } }) } req.body.server = server @@ -60,11 +60,11 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { router.post('/index', auth.required, async function (req: any, res) { const user = await User.findById(req.payload.id) if (!user) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.isAdmin() && !user.authorized) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (user.processing) { @@ -74,13 +74,13 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { const server = await Server.findOne({ slug: req.body.server }).populate('author') if (!server) { - return res.sendStatus(apiCode.not_found) + return res.status(apiCode.not_found) .json({ errors: { errors: 'Server not found' } }) } if ((server.author.username !== user.username) && (!user.isAdmin())) { console.log(server.author.username) console.log(user.username) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } @@ -107,11 +107,11 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { router.post('/check', auth.required, upload.single('file'), async function (req: any, res) { const user = await User.findById(req.payload.id) if (!user) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.isAdmin() && !user.authorized) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (user.processing) { @@ -120,13 +120,13 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { const server = await Server.findOne({ slug: req.body.server }).populate('author') if (!server) { - return res.sendStatus(apiCode.not_found) + return res.status(apiCode.not_found) .json({ errors: { errors: 'Server not found' } }) } if ((server.author.username !== user.username) && (!user.isAdmin())) { console.log(server.author.username) console.log(user.username) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!req.file) { @@ -165,11 +165,11 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { router.post('/full', auth.required, upload.single('file'), async function (req: any, res) { const user = await User.findById(req.payload.id) if (!user) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.isAdmin() && !user.authorized) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (user.processing) { @@ -179,13 +179,13 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { const server = await Server.findOne({ slug: req.body.server }).populate('author') if (!server) { - return res.sendStatus(apiCode.not_found) + return res.status(apiCode.not_found) .json({ errors: { errors: 'Server not found' } }) } if ((server.author.username !== user.username) && (!user.isAdmin())) { console.log(server.author.username) console.log(user.username) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!req.file) { @@ -238,11 +238,11 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { router.post('/url', auth.required, async function (req: any, res) { const user = await User.findById(req.payload.id) if (!user) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.isAdmin() && !user.authorized) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (user.processing) { @@ -251,11 +251,11 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { const server = await Server.findOne({ slug: req.body.server }).populate('author') if (!server) { - return res.sendStatus(apiCode.not_found) + return res.status(apiCode.not_found) .json({ errors: { errors: 'Server not found' } }) } if ((server.author.username !== user.username) && (!user.isAdmin())) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } @@ -292,11 +292,11 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { router.post('/send', auth.required, async function (req: any, res: any) { const user = await User.findById(req.payload.id) if (!user) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.isAdmin() && !user.authorized) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (user.processing) { return res.sendStatus(apiCode.forbidden) } @@ -304,11 +304,11 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { const server = await Server.findOne({ slug: req.body.server }).populate('author') if (!server) { - return res.sendStatus(apiCode.not_found) + return res.status(apiCode.not_found) .json({ errors: { errors: 'Not found' } }) } if ((server.author.username !== user.username) && (!user.isAdmin())) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } @@ -345,11 +345,11 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { router.post('/download/:server', auth.required, async function (req: any, res) { const user = await User.findById(req.payload.id) if (!user) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.isAdmin() && !user.authorized) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (user.processing) { return res.sendStatus(apiCode.forbidden) } @@ -358,7 +358,7 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { if ((server.author.username !== user.username) && (!user.isAdmin())) { console.log(server.author.username) console.log(user.username) - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } diff --git a/BackEnd/src/controllers/users.ts b/BackEnd/src/controllers/users.ts index 4d0289c..718fdc4 100644 --- a/BackEnd/src/controllers/users.ts +++ b/BackEnd/src/controllers/users.ts @@ -20,7 +20,7 @@ export function userAPI (cloud: CloudService) { router.get('/user', auth.required, async function (req: any, res) { const user = await User.findById(req.payload.id) if (!user) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } @@ -51,7 +51,7 @@ export function userAPI (cloud: CloudService) { const user = await User.findById(req.payload.id) if (!user || !user.isAdmin()) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (user.isAdmin()) { @@ -63,15 +63,15 @@ export function userAPI (cloud: CloudService) { router.put('/user', auth.required, async function (req: any, res, next) { const user = await User.findById(req.payload.id) if (!user) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.active) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.isAdmin() && !user.authorized) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } @@ -136,15 +136,15 @@ export function userAPI (cloud: CloudService) { const user = await User.findById(req.payload.id) if (!user) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.active) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.isAdmin() && !user.authorized) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!req.body.user.email) { @@ -176,15 +176,15 @@ export function userAPI (cloud: CloudService) { router.post('/users/disable', auth.required, async function (req: any, res, next) { const user = await User.findById(req.payload.id) if (!user) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (!user.authorized && !user.isAdmin()) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } if (user.processing) { - return res.sendStatus(apiCode.forbidden) + return res.status(apiCode.forbidden) } if (!req.body.user.email) { @@ -315,8 +315,7 @@ export function userAPI (cloud: CloudService) { await cloud.deleteObjects(server.slug) console.log('swift container removed') - const serverDir = - path.join('./uploads', user.username, server.slug) + const serverDir = path.join('./uploads', user.username, server.slug) await fs.promises.rm(serverDir, { recursive: true }) console.log('server deleted from uploads') diff --git a/FrontEnd/src/app/delete-account/delete-account.component.ts b/FrontEnd/src/app/delete-account/delete-account.component.ts index 2503867..6959301 100644 --- a/FrontEnd/src/app/delete-account/delete-account.component.ts +++ b/FrontEnd/src/app/delete-account/delete-account.component.ts @@ -67,13 +67,15 @@ export class DeleteAccountComponent implements OnInit { } submitForm() { + const own_deletion = + this.user.username === this.deleteAccountForm.value.username_verification if (this.isAssuming && this.isChecked) { this.preForm(); this.userService .delete(this.deleteAccountForm.value, this.authForm.value) .subscribe( succes => { - if (!this.user.admin) + if (own_deletion) this.userService.purgeAuth(); this.router.navigateByUrl('/'); }, From b3f3ec491563ff939093c5810c8024a44c5c88e1 Mon Sep 17 00:00:00 2001 From: Astyax NOUREL Date: Thu, 24 Mar 2022 00:49:07 +0100 Subject: [PATCH 4/6] some fixes when getting a token or downloading archive --- BackEnd/src/controllers/server.ts | 4 ++-- BackEnd/src/controllers/upload.ts | 14 +++++++++++--- FrontEnd/src/app/server/server.component.ts | 2 +- .../server-helpers/server-preview.component.html | 2 +- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/BackEnd/src/controllers/server.ts b/BackEnd/src/controllers/server.ts index 7e263d8..0cf8d40 100644 --- a/BackEnd/src/controllers/server.ts +++ b/BackEnd/src/controllers/server.ts @@ -181,7 +181,7 @@ export function serverAPI (cloud: CloudService) { router.post('/disable/:server', auth.required, async function (req: any, res: any) { const user = await User.findById(req.payload.id) if (req.server.author._id.toString() !== req.payload.id.toString() && - user.isAdmin()) { + !user.isAdmin()) { log_functions.create('error', 'get /server/disable/:' + req.server.slug, log_message.user_owner_error, user, req.server) return res.sendStatus(apiCode.forbidden) @@ -356,7 +356,7 @@ export function serverAPI (cloud: CloudService) { const namespace = 'default' await user.startProcessing() - const token = server_functions.catchTeacherToken(slug, namespace) + const token = await server_functions.catchTeacherToken(slug, namespace) log_functions.create('bin', 'post /server/token:' + req.server.slug, log_message.user_token_ok, user, req.server) req.server.token = token diff --git a/BackEnd/src/controllers/upload.ts b/BackEnd/src/controllers/upload.ts index 2d2af7b..b250642 100644 --- a/BackEnd/src/controllers/upload.ts +++ b/BackEnd/src/controllers/upload.ts @@ -90,6 +90,7 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { await fs.promises.readFile(path.join(serverPath, 'exercises/index.json'), { encoding: 'utf8' }) .then(JSON.parse) + .then(index => index.groups) .catch(err => { if (err.code === 'ENOENT') { return [] } else { throw err } }) as { [id: string]: { exercises: string[] }} @@ -325,15 +326,17 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { const indexPath = path.join(exercisesPath, 'index.json') const groups = req.body.groups as { [id: string]: { title: string, exercises: string[] }} - const indexData = JSON.stringify(groups, null, 4) + const index = { learnocaml_version: '1', groups } + const indexData = JSON.stringify(index, null, 4) if (Object.keys(groups).length === 0) { return res.status(400).send({ errors: { file: ': No groups received' } }) } await fs.promises.writeFile(indexPath, indexData, 'utf8') + const repoDir = 'repository/exercises' const safePathData = - fileData(inPathData(exercisesPath), exercisesPath) as PathFileData + fileData(inPathData(exercisesPath), repoDir) as PathFileData const zipData = await archive.zipFromDir(safePathData, outBufferData) cloud.uploadObject(server.slug, 'repository.zip', zipData) @@ -352,7 +355,9 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { return res.status(apiCode.forbidden) .json({ errors: { errors: 'Unauthorized' } }) } - if (user.processing) { return res.sendStatus(apiCode.forbidden) } + if (user.processing) { + return res.sendStatus(apiCode.forbidden) + } const server = req.body.server if ((server.author.username !== user.username) && (!user.isAdmin())) { @@ -376,10 +381,13 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { .then(filesLists => filesLists.flat()) const allZip = await archive.zip(files, outBufferData) + await user.endProcessing() return res.send(allZip.input) } else { const zip = await cloud.downloadObject(server.slug, `${target}.zip`, outBufferData) + + await user.endProcessing() return res.send(zip.input) } }) diff --git a/FrontEnd/src/app/server/server.component.ts b/FrontEnd/src/app/server/server.component.ts index 8eb3e99..65b51c4 100644 --- a/FrontEnd/src/app/server/server.component.ts +++ b/FrontEnd/src/app/server/server.component.ts @@ -1,5 +1,4 @@ import { Component, OnInit } from '@angular/core'; -import { FormControl } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import { ModalService } from '../modal'; @@ -78,6 +77,7 @@ export class ServerComponent implements OnInit { .subscribe( success => { this.modalService.close('pleaseWait2'); + // bad modal service can lead to black screen after closing this.router.navigateByUrl('/'); } ); diff --git a/FrontEnd/src/app/shared/server-helpers/server-preview.component.html b/FrontEnd/src/app/shared/server-helpers/server-preview.component.html index d57e6f5..99c13ab 100644 --- a/FrontEnd/src/app/shared/server-helpers/server-preview.component.html +++ b/FrontEnd/src/app/shared/server-helpers/server-preview.component.html @@ -33,7 +33,7 @@

{{ server.description }} All - Exercises only + Repository only Sync only From 4f3d93e47b672aaae90549a6a71a754b0b058ec4 Mon Sep 17 00:00:00 2001 From: Astyax NOUREL Date: Thu, 24 Mar 2022 11:07:17 +0100 Subject: [PATCH 5/6] ignoring index.json in index request, ignoring all errors when deleting a server --- BackEnd/src/controllers/server.ts | 10 +++++----- BackEnd/src/controllers/upload.ts | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/BackEnd/src/controllers/server.ts b/BackEnd/src/controllers/server.ts index 0cf8d40..7e7f724 100644 --- a/BackEnd/src/controllers/server.ts +++ b/BackEnd/src/controllers/server.ts @@ -298,15 +298,15 @@ export function serverAPI (cloud: CloudService) { log_functions.create('bin', 'delete /server/:' + req.server.slug, log_message.user_processing_start, user) - await server_functions.removekubelink(slug, namespace) + await server_functions.removekubelink(slug, namespace).catch(console.error) console.log('kubelink removed') - await cloud.deleteObjects(slug) - await cloud.deleteContainer(slug) + await cloud.deleteObjects(slug).catch(console.error) + await cloud.deleteContainer(slug).catch(console.error) console.log('swift container removed') const serverDir = path.join('./uploads', user.username, slug) - await fs.promises.rm(serverDir, { recursive: true }) + await fs.promises.rm(serverDir, { recursive: true }).catch(console.error) console.log('server deleted') await user.endProcessing() @@ -314,7 +314,7 @@ export function serverAPI (cloud: CloudService) { log_message.user_processing_end, user) log_functions.create('bin', 'delete /server/:' + req.server.slug, log_message.server_deletion_ok, user, req.server) - await req.server.remove() + await req.server.remove().catch(console.error) return res.sendStatus(apiCode.ok) }) diff --git a/BackEnd/src/controllers/upload.ts b/BackEnd/src/controllers/upload.ts index b250642..7184072 100644 --- a/BackEnd/src/controllers/upload.ts +++ b/BackEnd/src/controllers/upload.ts @@ -98,7 +98,8 @@ export function uploadAPI (cloud: CloudService, archive: ArchiveService) { const usedList = Object.values(groups).flatMap(group => group.exercises) const exercisesList = await fs.promises.readdir(path.join(serverPath, 'exercises')) - .then(files => files.filter(file => !usedList.includes(file))) + .then(files => files.filter(file => + !usedList.includes(file) && file !== 'index.json')) .catch(err => { if (err.code === 'ENOENT') { return [] } else { throw err } }) From 93fb74228dd6e9adc38c504cd6068bd594cac79b Mon Sep 17 00:00:00 2001 From: Astyax NOUREL Date: Thu, 24 Mar 2022 11:39:30 +0100 Subject: [PATCH 6/6] removing weird behaviour of modal when closing a server instance --- FrontEnd/src/app/server/server.component.html | 1 + FrontEnd/src/app/server/server.component.ts | 7 ++----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/FrontEnd/src/app/server/server.component.html b/FrontEnd/src/app/server/server.component.html index 61e18b2..fe4f0a9 100644 --- a/FrontEnd/src/app/server/server.component.html +++ b/FrontEnd/src/app/server/server.component.html @@ -8,6 +8,7 @@ Manage Server