diff --git a/package-lock.json b/package-lock.json index 2ee11e36..35b159d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,8 +28,6 @@ "multer": "^2.0.1", "on-finished": "^2.4.1", "public-ip": "^7.0.1", - "recursive-readdir": "^2.2.3", - "request": "^2.88.2", "require-from-string": "^2.0.2", "serve-favicon": "~2.5.1", "shell-quote": "^1.8.3", @@ -42,7 +40,6 @@ }, "devDependencies": { "@eslint/js": "^9.39.5", - "@types/bcryptjs": "^3.0.0", "@types/configstore": "^5.0.1", "@types/cookie-parser": "^1.4.9", "@types/debug": "^4.1.12", @@ -53,19 +50,14 @@ "@types/http-proxy": "^1.17.16", "@types/is-valid-path": "^0.1.2", "@types/jest": "^29.5.14", - "@types/js-base64": "^3.3.1", "@types/jsonwebtoken": "^9.0.10", - "@types/moment": "^2.13.0", "@types/morgan": "^1.9.10", "@types/multer": "^2.0.0", "@types/on-finished": "^2.3.5", - "@types/request": "^2.48.12", "@types/require-from-string": "^1.2.3", "@types/serve-favicon": "^2.5.7", "@types/shell-quote": "^1.7.5", "@types/ssh2": "^1.15.5", - "@types/tar": "^6.1.13", - "@types/uuid": "^10.0.0", "@types/validator": "^13.15.2", "eslint": "^9.39.5", "globals": "^16.3.0", @@ -2641,17 +2633,6 @@ "@babel/types": "^7.28.2" } }, - "node_modules/@types/bcryptjs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-3.0.0.tgz", - "integrity": "sha512-WRZOuCuaz8UcZZE4R5HXTco2goQSI2XxjGY3hbM/xDvwmqFWd4ivooImsMx65OKM6CtNKbnZ5YL+YwAwK7c1dg==", - "deprecated": "This is a stub types definition. bcryptjs provides its own type definitions, so you do not need this installed.", - "dev": true, - "license": "MIT", - "dependencies": { - "bcryptjs": "*" - } - }, "node_modules/@types/body-parser": { "version": "1.19.6", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", @@ -2663,13 +2644,6 @@ "@types/node": "*" } }, - "node_modules/@types/caseless": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", - "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/configstore": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@types/configstore/-/configstore-5.0.1.tgz", @@ -2848,17 +2822,6 @@ "pretty-format": "^29.0.0" } }, - "node_modules/@types/js-base64": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@types/js-base64/-/js-base64-3.3.1.tgz", - "integrity": "sha512-Zw33oQNAvDdAN9b0IE5stH0y2MylYvtU7VVTKEJPxhyM2q57CVaNJhtJW258ah24NRtaiA23tptUmVn3dmTKpw==", - "deprecated": "This is a stub types definition. js-base64 provides its own type definitions, so you do not need this installed.", - "dev": true, - "license": "MIT", - "dependencies": { - "js-base64": "*" - } - }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -2893,17 +2856,6 @@ "integrity": "sha512-jJ41Q4z6ZVO260MNDdHfW7+7a5iMiX8Mr6ZJHcmgrvhZha6dz5704o/lF2kKl6URjH6ivEL97w9xS/MgpJEphg==", "license": "MIT" }, - "node_modules/@types/moment": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/@types/moment/-/moment-2.13.0.tgz", - "integrity": "sha512-DyuyYGpV6r+4Z1bUznLi/Y7HpGn4iQ4IVcGn8zrr1P4KotKLdH0sbK1TFR6RGyX6B+G8u83wCzL+bpawKU/hdQ==", - "deprecated": "This is a stub types definition for Moment (https://github.com/moment/moment). Moment provides its own type definitions, so you don't need @types/moment installed!", - "dev": true, - "license": "MIT", - "dependencies": { - "moment": "*" - } - }, "node_modules/@types/morgan": { "version": "1.9.10", "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.10.tgz", @@ -2964,19 +2916,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/request": { - "version": "2.48.13", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.13.tgz", - "integrity": "sha512-FGJ6udDNUCjd19pp0Q3iTiDkwhYup7J8hpMW9c4k53NrccQFFWKRho6hvtPPEhnXWKvukfwAlB6DbDz4yhH5Gg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/caseless": "*", - "@types/node": "*", - "@types/tough-cookie": "*", - "form-data": "^2.5.5" - } - }, "node_modules/@types/require-from-string": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@types/require-from-string/-/require-from-string-1.2.3.tgz", @@ -3056,31 +2995,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/tar": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/@types/tar/-/tar-6.1.13.tgz", - "integrity": "sha512-IznnlmU5f4WcGTh2ltRu/Ijpmk8wiWXfF0VA4s+HPjHZgvFggk1YaIkbo5krX/zUCzWF8N/l4+W/LNxnvAJ8nw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "minipass": "^4.0.0" - } - }, - "node_modules/@types/tough-cookie": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/validator": { "version": "13.15.10", "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.10.tgz", @@ -3833,6 +3747,7 @@ "version": "6.15.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -3948,15 +3863,6 @@ "safer-buffer": "~2.1.0" } }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, "node_modules/ast-module-types": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-6.0.2.tgz", @@ -3979,21 +3885,6 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", - "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", - "license": "MIT" - }, "node_modules/axios": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/axios/-/axios-1.20.0.tgz", @@ -4256,6 +4147,7 @@ "version": "1.1.18", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -4494,12 +4386,6 @@ ], "license": "CC-BY-4.0" }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "license": "Apache-2.0" - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -4705,6 +4591,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, "license": "MIT" }, "node_modules/concat-stream": { @@ -4812,12 +4699,6 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "license": "MIT" }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "license": "MIT" - }, "node_modules/cpu-features": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz", @@ -4873,18 +4754,6 @@ "node": ">=8" } }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -5316,16 +5185,6 @@ "dev": true, "license": "MIT" }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "license": "MIT", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -5842,31 +5701,18 @@ "node": ">=6.6.0" } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "engines": [ - "node >=0.6.0" - ], - "license": "MIT" - }, "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, "license": "MIT" }, "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", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { @@ -6105,33 +5951,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.6.tgz", - "integrity": "sha512-Ogz/E85h9tlfJzpI6TuFpGcHZFhLrb9Gw8wq9v40CxSCPnv7ahKr6Xgtkn0KYCDQJ8DNn5VoMO8EXr9V5PadyA==", - "dev": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.4", - "mime-types": "^2.1.35", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.12" - } - }, "node_modules/form-data-encoder": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", @@ -6141,29 +5960,6 @@ "node": ">= 14.17" } }, - "node_modules/form-data/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/form-data/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -6322,15 +6118,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/glob": { "version": "13.0.6", "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", @@ -6505,29 +6292,6 @@ "uglify-js": "^3.1.4" } }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "license": "ISC", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "license": "MIT", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -6624,21 +6388,6 @@ "node": ">=8.0.0" } }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, "node_modules/http2-wrapper": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", @@ -7024,12 +6773,6 @@ "dev": true, "license": "ISC" }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "license": "MIT" - }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -8580,12 +8323,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "license": "MIT" - }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -8612,16 +8349,11 @@ "dev": true, "license": "MIT" }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "license": "(AFL-2.1 OR BSD-3-Clause)" - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { @@ -8631,12 +8363,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "license": "ISC" - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -8696,21 +8422,6 @@ "node": ">=10" } }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "license": "MIT", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/jwa": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", @@ -9094,6 +8805,7 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -9112,16 +8824,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, "node_modules/minizlib": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", @@ -9450,15 +9152,6 @@ "node": ">=8" } }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -9742,12 +9435,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "license": "MIT" - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -10078,18 +9765,6 @@ "node": ">=10" } }, - "node_modules/psl": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", - "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", - "license": "MIT", - "dependencies": { - "punycode": "^2.3.1" - }, - "funding": { - "url": "https://github.com/sponsors/lupomontero" - } - }, "node_modules/public-ip": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/public-ip/-/public-ip-7.0.1.tgz", @@ -10121,6 +9796,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -10253,104 +9929,6 @@ "node": ">= 6" } }, - "node_modules/recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "license": "MIT", - "dependencies": { - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "license": "Apache-2.0", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/request/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/request/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.5.tgz", - "integrity": "sha512-mzR4sElr1bfCaPJe7m8ilJ6ZXdDaGoObcYR0ZHSsktM/Lt21MVHj5De30GQH2eiZ1qGRTO7LCAzQsUeXTNexWQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", - "license": "MIT", - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -10847,31 +10425,6 @@ "nan": "^2.23.0" } }, - "node_modules/sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "license": "MIT", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -11423,19 +10976,6 @@ "node": ">=0.6" } }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "license": "BSD-3-Clause", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/ts-api-utils": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", @@ -11587,18 +11127,6 @@ "license": "0BSD", "optional": true }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", @@ -11835,6 +11363,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" @@ -11892,20 +11421,6 @@ "node": ">= 0.8" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "node_modules/walkdir": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", diff --git a/package.json b/package.json index 3ae64800..1f395ab4 100644 --- a/package.json +++ b/package.json @@ -34,8 +34,6 @@ "multer": "^2.0.1", "on-finished": "^2.4.1", "public-ip": "^7.0.1", - "recursive-readdir": "^2.2.3", - "request": "^2.88.2", "require-from-string": "^2.0.2", "serve-favicon": "~2.5.1", "shell-quote": "^1.8.3", @@ -48,7 +46,6 @@ }, "devDependencies": { "@eslint/js": "^9.39.5", - "@types/bcryptjs": "^3.0.0", "@types/configstore": "^5.0.1", "@types/cookie-parser": "^1.4.9", "@types/debug": "^4.1.12", @@ -59,19 +56,14 @@ "@types/http-proxy": "^1.17.16", "@types/is-valid-path": "^0.1.2", "@types/jest": "^29.5.14", - "@types/js-base64": "^3.3.1", "@types/jsonwebtoken": "^9.0.10", - "@types/moment": "^2.13.0", "@types/morgan": "^1.9.10", "@types/multer": "^2.0.0", "@types/on-finished": "^2.3.5", - "@types/request": "^2.48.12", "@types/require-from-string": "^1.2.3", "@types/serve-favicon": "^2.5.7", "@types/shell-quote": "^1.7.5", "@types/ssh2": "^1.15.5", - "@types/tar": "^6.1.13", - "@types/uuid": "^10.0.0", "@types/validator": "^13.15.2", "eslint": "^9.39.5", "globals": "^16.3.0", diff --git a/src/user/system/CaptainManager.ts b/src/user/system/CaptainManager.ts index 86b6a133..3c6fb236 100644 --- a/src/user/system/CaptainManager.ts +++ b/src/user/system/CaptainManager.ts @@ -7,6 +7,7 @@ import { GoAccessInfo } from '../../models/GoAccessInfo' import { IRegistryInfo, IRegistryTypes } from '../../models/IRegistryInfo' import { NetDataInfo } from '../../models/NetDataInfo' import CaptainConstants from '../../utils/CaptainConstants' +import { getText } from '../../utils/HttpUtils' import Logger from '../../utils/Logger' import Utils from '../../utils/Utils' import Authenticator from '../Authenticator' @@ -24,7 +25,6 @@ import DiskCleanupManager from './DiskCleanupManager' import DomainResolveChecker from './DomainResolveChecker' import LoadBalancerManager from './LoadBalancerManager' import SelfHostedDockerRegistry from './SelfHostedDockerRegistry' -import request = require('request') import fs = require('fs-extra') const DEBUG_SALT = 'THIS IS NOT A REAL CERTIFICATE' @@ -339,22 +339,26 @@ class CaptainManager { const url = `http://${captainPublicDomain}${CaptainConstants.healthCheckEndPoint}` - request( - url, - - function (error, response, body) { + getText(url) + .then(function (body) { if (callbackCalled) { return } callbackCalled = true - if (error || !body || body !== self.getHealthCheckUuid()) { + if (!body || body !== self.getHealthCheckUuid()) { callback(false) } else { callback(true) } - } - ) + }) + .catch(function () { + if (callbackCalled) { + return + } + callbackCalled = true + callback(false) + }) } function checkNginxHealth(callback: ISuccessCallback) { diff --git a/src/user/system/DomainResolveChecker.ts b/src/user/system/DomainResolveChecker.ts index f3a0a376..e12aaf46 100644 --- a/src/user/system/DomainResolveChecker.ts +++ b/src/user/system/DomainResolveChecker.ts @@ -1,11 +1,11 @@ import { v4 as uuid } from 'uuid' import ApiStatusCodes from '../../api/ApiStatusCodes' import CaptainConstants from '../../utils/CaptainConstants' +import { getText } from '../../utils/HttpUtils' import Logger from '../../utils/Logger' import Utils from '../../utils/Utils' import CertbotManager from './CertbotManager' import LoadBalancerManager from './LoadBalancerManager' -import request = require('request') import fs = require('fs-extra') export default class DomainResolveChecker { @@ -64,15 +64,12 @@ export default class DomainResolveChecker { return new Promise(function (resolve, reject) { const url = `http://${domainName}:${CaptainConstants.configs.nginxPortNumber80}${captainConfirmationPath}` - request( - url, - - function (error, response, body) { - if (error || !body || body !== randomUuid) { + getText(url) + .then(function (body) { + if (!body || body !== randomUuid) { Logger.e( `Verification Failed for ${domainName}` ) - Logger.e(`Error ${error}`) Logger.e(`body ${body}`) Logger.e(`randomUuid ${randomUuid}`) reject( @@ -85,8 +82,17 @@ export default class DomainResolveChecker { } resolve() - } - ) + }) + .catch(function (error) { + Logger.e(`Verification Failed for ${domainName}`) + Logger.e(`Error ${error}`) + reject( + ApiStatusCodes.createError( + ApiStatusCodes.VERIFICATION_FAILED, + 'Verification Failed.' + ) + ) + }) }) }) } @@ -103,24 +109,32 @@ export default class DomainResolveChecker { Logger.d(`Sending request to ${url}`) - request(url, function (error, response, body) { - if ( - error || - !body || - body !== - self.loadBalancerManager.getCaptainPublicRandomKey() - ) { + getText(url) + .then(function (body) { + if ( + !body || + body !== + self.loadBalancerManager.getCaptainPublicRandomKey() + ) { + reject( + ApiStatusCodes.createError( + ApiStatusCodes.VERIFICATION_FAILED, + 'Verification Failed.' + ) + ) + return + } + + resolve() + }) + .catch(function () { reject( ApiStatusCodes.createError( ApiStatusCodes.VERIFICATION_FAILED, 'Verification Failed.' ) ) - return - } - - resolve() - }) + }) }) } } diff --git a/src/user/system/LoadBalancerManager.ts b/src/user/system/LoadBalancerManager.ts index e4494feb..c63e24ae 100644 --- a/src/user/system/LoadBalancerManager.ts +++ b/src/user/system/LoadBalancerManager.ts @@ -11,10 +11,10 @@ import { IServerBlockDetails } from '../../models/IServerBlockDetails' import LoadBalancerInfo from '../../models/LoadBalancerInfo' import { AnyError } from '../../models/OtherTypes' import CaptainConstants from '../../utils/CaptainConstants' +import { getText } from '../../utils/HttpUtils' import Logger from '../../utils/Logger' import CertbotManager from './CertbotManager' import fs = require('fs-extra') -import request = require('request') const exec = util.promisify(chileProcess.exec) const defaultPageTemplate = fs @@ -439,8 +439,46 @@ class LoadBalancerManager { return new Promise(function (resolve, reject) { const url = `http://${CaptainConstants.nginxServiceName}/nginx_status` - request(url, function (error, response, body) { - if (error || !body) { + getText(url).then( + function (body) { + if (!body) { + reject( + ApiStatusCodes.createError( + ApiStatusCodes.STATUS_ERROR_GENERIC, + 'Request to nginx Failed.' + ) + ) + return + } + + try { + const data = new LoadBalancerInfo() + const lines = body.split('\n') + + data.activeConnections = Number( + lines[0].split(' ')[2].trim() + ) + + data.accepted = Number(lines[2].split(' ')[1].trim()) + data.handled = Number(lines[2].split(' ')[2].trim()) + data.total = Number(lines[2].split(' ')[3].trim()) + + data.reading = Number(lines[3].split(' ')[1].trim()) + data.writing = Number(lines[3].split(' ')[3].trim()) + data.waiting = Number(lines[3].split(' ')[5].trim()) + + resolve(data) + } catch (error) { + Logger.e(error) + reject( + ApiStatusCodes.createError( + ApiStatusCodes.STATUS_ERROR_GENERIC, + 'Parser Failed. See internal logs...' + ) + ) + } + }, + function (error) { Logger.e(`Error ${error}`) reject( ApiStatusCodes.createError( @@ -448,36 +486,8 @@ class LoadBalancerManager { 'Request to nginx Failed.' ) ) - return } - - try { - const data = new LoadBalancerInfo() - const lines = body.split('\n') - - data.activeConnections = Number( - lines[0].split(' ')[2].trim() - ) - - data.accepted = Number(lines[2].split(' ')[1].trim()) - data.handled = Number(lines[2].split(' ')[2].trim()) - data.total = Number(lines[2].split(' ')[3].trim()) - - data.reading = Number(lines[3].split(' ')[1].trim()) - data.writing = Number(lines[3].split(' ')[3].trim()) - data.waiting = Number(lines[3].split(' ')[5].trim()) - - resolve(data) - } catch (error) { - Logger.e(error) - reject( - ApiStatusCodes.createError( - ApiStatusCodes.STATUS_ERROR_GENERIC, - 'Parser Failed. See internal logs...' - ) - ) - } - }) + ) }) } diff --git a/src/user/system/VersionManager.ts b/src/user/system/VersionManager.ts index b3af2785..8975e08f 100644 --- a/src/user/system/VersionManager.ts +++ b/src/user/system/VersionManager.ts @@ -1,7 +1,7 @@ -import request = require('request') import axios from 'axios' import DockerApi from '../../docker/DockerApi' import CaptainConstants from '../../utils/CaptainConstants' +import { getText } from '../../utils/HttpUtils' import Logger from '../../utils/Logger' import DockerRegistryHelper from '../DockerRegistryHelper' @@ -78,18 +78,14 @@ class VersionManager { const url = `https://hub.docker.com/v2/repositories/${CaptainConstants.configs.publishedNameOnDockerHub}/tags` return new Promise(function (resolve, reject) { - request( - url, - - function (error, response, body) { + getText(url) + .then(function (body) { if (CaptainConstants.isDebug) { resolve(['v0.0.1']) return } - if (error) { - reject(error) - } else if (!body || !JSON.parse(body).results) { + if (!body || !JSON.parse(body).results) { reject( new Error( 'Received empty body or no result for version list on docker hub.' @@ -103,8 +99,8 @@ class VersionManager { } resolve(tags) } - } - ) + }) + .catch(reject) }).then(function (tagList) { const currentVersion = CaptainConstants.configs.version.split('.') let latestVersion = CaptainConstants.configs.version.split('.') diff --git a/src/utils/CaptainInstaller.ts b/src/utils/CaptainInstaller.ts index 9cbcfdab..a8ba7973 100644 --- a/src/utils/CaptainInstaller.ts +++ b/src/utils/CaptainInstaller.ts @@ -3,8 +3,8 @@ import { IAppEnvVar, IAppPort } from '../models/AppDefinition' import BackupManager from '../user/system/BackupManager' import CaptainConstants from './CaptainConstants' import EnvVar from './EnvVars' +import { getText } from './HttpUtils' import http = require('http') -import request = require('request') // internal IP returns Public IP if the machine is not behind a NAT // No need to directly use Public IP. @@ -246,9 +246,8 @@ function checkPortOrThrow(ipAddr: string, portToTest: number) { reject(new Error(`Port timed out: ${portToTest}`)) }, 5000) - request( - `http://${ipAddr}:${portToTest}`, - function (error, response, body) { + getText(`http://${ipAddr}:${portToTest}`) + .then(function (body) { if (finished) { return } @@ -261,8 +260,16 @@ function checkPortOrThrow(ipAddr: string, portToTest: number) { printError() reject(new Error(`Port seems to be closed: ${portToTest}`)) } - } - ) + }) + .catch(function () { + if (finished) { + return + } + + finished = true + printError() + reject(new Error(`Port seems to be closed: ${portToTest}`)) + }) }) } diff --git a/src/utils/HttpUtils.ts b/src/utils/HttpUtils.ts new file mode 100644 index 00000000..8c0e1e06 --- /dev/null +++ b/src/utils/HttpUtils.ts @@ -0,0 +1,11 @@ +import axios from 'axios' + +export function getText(url: string): Promise { + return axios + .get(url, { + responseType: 'text', + transformResponse: [(data) => data], + validateStatus: () => true, + }) + .then((response) => response.data) +} diff --git a/src/utils/TemplateHelperVersionPrinter.ts b/src/utils/TemplateHelperVersionPrinter.ts index 403d469c..45ddcf6c 100644 --- a/src/utils/TemplateHelperVersionPrinter.ts +++ b/src/utils/TemplateHelperVersionPrinter.ts @@ -1,7 +1,7 @@ -import request = require('request') import ApiStatusCodes from '../api/ApiStatusCodes' import { IHashMapGeneric } from '../models/ICacheGeneric' import { ITemplate } from '../models/OtherTypes' +import { getText } from './HttpUtils' import Logger from './Logger' function getTagsForImage( @@ -14,27 +14,25 @@ function getTagsForImage( } return new Promise(function (resolve, reject) { - request( - url!, - - function (error, response, body) { - if (error || !body) { - Logger.e(error) - reject(error) + getText(url!) + .then(function (body) { + if (!body) { + reject(new Error('Received empty response from Docker Hub')) return } + let parsedBody: any try { // Sometimes Docker server is down and it crashes Captain! - body = JSON.parse(body) + parsedBody = JSON.parse(body) } catch (e) { Logger.e(e) } let results: any - if (body) { - results = body.results + if (parsedBody) { + results = parsedBody.results } if (!results) { @@ -51,14 +49,19 @@ function getTagsForImage( allTags.push(results[idx].name) } - if (body.next) { - resolve(getTagsForImage(imageBaseName, body.next, allTags)) + if (parsedBody.next) { + resolve( + getTagsForImage(imageBaseName, parsedBody.next, allTags) + ) return } resolve(allTags) - } - ) + }) + .catch(function (error) { + Logger.e(error) + reject(error) + }) }) } diff --git a/tests/HttpUtils.test.ts b/tests/HttpUtils.test.ts new file mode 100644 index 00000000..7d290906 --- /dev/null +++ b/tests/HttpUtils.test.ts @@ -0,0 +1,43 @@ +import axios from 'axios' +import { getText } from '../src/utils/HttpUtils' + +jest.mock('axios') + +const mockedAxios = axios as jest.Mocked + +describe('HttpUtils', () => { + beforeEach(() => { + jest.clearAllMocks() + }) + + test('returns the response body as text', async () => { + mockedAxios.get.mockResolvedValue({ data: 'response body' }) + + await expect(getText('https://example.com')).resolves.toBe( + 'response body' + ) + + expect(mockedAxios.get).toHaveBeenCalledWith( + 'https://example.com', + expect.objectContaining({ responseType: 'text' }) + ) + }) + + test('preserves response bodies for every HTTP status', async () => { + mockedAxios.get.mockResolvedValue({ data: 'not found' }) + + await expect(getText('https://example.com/missing')).resolves.toBe( + 'not found' + ) + + const config = mockedAxios.get.mock.calls[0][1] + expect(config?.validateStatus?.(404)).toBe(true) + }) + + test('rejects network failures', async () => { + const error = new Error('network failure') + mockedAxios.get.mockRejectedValue(error) + + await expect(getText('https://example.com')).rejects.toBe(error) + }) +})