0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-12-16 21:56:25 -05:00

feat: refactor render middleware and audit plugin (#3602)

* chore: replace web middleware

* clean up

* migrate user agent

* migrate rate limit

* clean up

* replace audit plugin

* feat: refactor render middleware and audit plugin

* update deps

* update deps

* update packages

* update deps

* chore: update deps

* update deps

* update config dep

* chore: update deps

* update deps
This commit is contained in:
Juan Picado 2023-02-14 22:20:11 +01:00 committed by GitHub
parent bf9ed26d90
commit f9f269ee04
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 181 additions and 877 deletions

195
.pnp.cjs generated
View file

@ -55,7 +55,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["@trivago/prettier-plugin-sort-imports", "virtual:7f7b3df50ee4b7b1719ad19fad11505dc2788f3227a7e5cc9ca19f71d8cb309c9d33b532ea2b2b60ab65abf6cc12153df4643c5e6e17d01ea0ae0492723bb4b4#npm:4.0.0"],\
["@types/async", "npm:3.2.16"],\
["@types/express", "npm:4.17.14"],\
["@types/express-rate-limit", "npm:5.1.3"],\
["@types/express-serve-static-core", "npm:4.17.28"],\
["@types/http-errors", "npm:2.0.1"],\
["@types/jest", "npm:26.0.24"],\
@ -69,17 +68,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["@typescript-eslint/eslint-plugin", "virtual:7f7b3df50ee4b7b1719ad19fad11505dc2788f3227a7e5cc9ca19f71d8cb309c9d33b532ea2b2b60ab65abf6cc12153df4643c5e6e17d01ea0ae0492723bb4b4#npm:5.49.0"],\
["@typescript-eslint/parser", "virtual:7f7b3df50ee4b7b1719ad19fad11505dc2788f3227a7e5cc9ca19f71d8cb309c9d33b532ea2b2b60ab65abf6cc12153df4643c5e6e17d01ea0ae0492723bb4b4#npm:5.49.0"],\
["@verdaccio-scope/verdaccio-auth-foo", "npm:0.0.2"],\
["@verdaccio/config", "npm:6.0.0-6-next.55"],\
["@verdaccio/core", "npm:6.0.0-6-next.59"],\
["@verdaccio/config", "npm:6.0.0-6-next.61"],\
["@verdaccio/core", "npm:6.0.0-6-next.61"],\
["@verdaccio/local-storage", "npm:10.3.1"],\
["@verdaccio/logger-7", "npm:6.0.0-6-next.4"],\
["@verdaccio/middleware", "npm:6.0.0-6-next.38"],\
["@verdaccio/logger-7", "npm:6.0.0-6-next.6"],\
["@verdaccio/middleware", "npm:6.0.0-6-next.40"],\
["@verdaccio/streams", "npm:10.2.0"],\
["@verdaccio/tarball", "npm:11.0.0-6-next.28"],\
["@verdaccio/tarball", "npm:11.0.0-6-next.30"],\
["@verdaccio/types", "npm:10.7.0"],\
["@verdaccio/ui-theme", "npm:6.0.0-6-next.59"],\
["@verdaccio/url", "npm:11.0.0-6-next.25"],\
["@verdaccio/utils", "npm:6.0.0-6-next.27"],\
["@verdaccio/ui-theme", "npm:3.4.1"],\
["@verdaccio/url", "npm:11.0.0-6-next.27"],\
["@verdaccio/utils", "npm:6.0.0-6-next.29"],\
["JSONStream", "npm:1.3.5"],\
["async", "npm:3.2.4"],\
["babel-eslint", "virtual:7f7b3df50ee4b7b1719ad19fad11505dc2788f3227a7e5cc9ca19f71d8cb309c9d33b532ea2b2b60ab65abf6cc12153df4643c5e6e17d01ea0ae0492723bb4b4#npm:10.1.0"],\
@ -104,7 +103,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["eslint-plugin-simple-import-sort", "virtual:7f7b3df50ee4b7b1719ad19fad11505dc2788f3227a7e5cc9ca19f71d8cb309c9d33b532ea2b2b60ab65abf6cc12153df4643c5e6e17d01ea0ae0492723bb4b4#npm:9.0.0"],\
["eslint-plugin-verdaccio", "npm:10.0.0"],\
["express", "npm:4.18.2"],\
["express-rate-limit", "npm:5.5.1"],\
["fast-safe-stringify", "npm:2.1.1"],\
["fs-extra", "npm:10.1.0"],\
["get-port", "npm:5.1.1"],\
@ -120,7 +118,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["lint-staged", "npm:11.0.1"],\
["lockfile-lint", "npm:4.6.2"],\
["lodash", "npm:4.17.21"],\
["lru-cache", "npm:7.14.1"],\
["lunr-mutable-indexes", "npm:2.3.2"],\
["mime", "npm:3.0.0"],\
["mkdirp", "npm:1.0.4"],\
@ -139,7 +136,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["ts-node", "virtual:7f7b3df50ee4b7b1719ad19fad11505dc2788f3227a7e5cc9ca19f71d8cb309c9d33b532ea2b2b60ab65abf6cc12153df4643c5e6e17d01ea0ae0492723bb4b4#npm:10.9.1"],\
["typescript", "patch:typescript@npm%3A4.1.3#~builtin<compat/typescript>::version=4.1.3&hash=4a8eb8"],\
["validator", "npm:13.7.0"],\
["verdaccio-audit", "npm:10.2.4"],\
["verdaccio-audit", "npm:11.0.0-6-next.23"],\
["verdaccio-auth-memory", "npm:10.2.0"],\
["verdaccio-htpasswd", "npm:10.5.2"],\
["verdaccio-memory", "npm:10.3.0"]\
@ -3848,27 +3845,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["@types/serve-static", "npm:1.13.10"]\
],\
"linkType": "HARD"\
}],\
["npm:4.17.17", {\
"packageLocation": "./.yarn/cache/@types-express-npm-4.17.17-46fe8173db-0196dacc27.zip/node_modules/@types/express/",\
"packageDependencies": [\
["@types/express", "npm:4.17.17"],\
["@types/body-parser", "npm:1.19.2"],\
["@types/express-serve-static-core", "npm:4.17.33"],\
["@types/qs", "npm:6.9.7"],\
["@types/serve-static", "npm:1.13.10"]\
],\
"linkType": "HARD"\
}]\
]],\
["@types/express-rate-limit", [\
["npm:5.1.3", {\
"packageLocation": "./.yarn/cache/@types-express-rate-limit-npm-5.1.3-9d611672fc-44c0b79e48.zip/node_modules/@types/express-rate-limit/",\
"packageDependencies": [\
["@types/express-rate-limit", "npm:5.1.3"],\
["@types/express", "npm:4.17.17"]\
],\
"linkType": "HARD"\
}]\
]],\
["@types/express-serve-static-core", [\
@ -4497,12 +4473,12 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["@verdaccio/config", [\
["npm:6.0.0-6-next.55", {\
"packageLocation": "./.yarn/cache/@verdaccio-config-npm-6.0.0-6-next.55-ade614a724-6af29e3e1e.zip/node_modules/@verdaccio/config/",\
["npm:6.0.0-6-next.60", {\
"packageLocation": "./.yarn/cache/@verdaccio-config-npm-6.0.0-6-next.60-f4e4316ecc-93e7e22a65.zip/node_modules/@verdaccio/config/",\
"packageDependencies": [\
["@verdaccio/config", "npm:6.0.0-6-next.55"],\
["@verdaccio/core", "npm:6.0.0-6-next.55"],\
["@verdaccio/utils", "npm:6.0.0-6-next.23"],\
["@verdaccio/config", "npm:6.0.0-6-next.60"],\
["@verdaccio/core", "npm:6.0.0-6-next.60"],\
["@verdaccio/utils", "npm:6.0.0-6-next.28"],\
["debug", "virtual:1eb3a4b7acf39cc06579ce173dfc189db60be09511a857cde17cd58b8e2d244d4d50cb2c180dd19733a7495da9bca01fbe9bd6534c33688ce8846c8c32165184#npm:4.3.4"],\
["lodash", "npm:4.17.21"],\
["minimatch", "npm:3.1.2"],\
@ -4510,13 +4486,27 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["yup", "npm:0.32.11"]\
],\
"linkType": "HARD"\
}],\
["npm:6.0.0-6-next.61", {\
"packageLocation": "./.yarn/cache/@verdaccio-config-npm-6.0.0-6-next.61-304a700d80-268eff6e85.zip/node_modules/@verdaccio/config/",\
"packageDependencies": [\
["@verdaccio/config", "npm:6.0.0-6-next.61"],\
["@verdaccio/core", "npm:6.0.0-6-next.61"],\
["@verdaccio/utils", "npm:6.0.0-6-next.29"],\
["debug", "virtual:1eb3a4b7acf39cc06579ce173dfc189db60be09511a857cde17cd58b8e2d244d4d50cb2c180dd19733a7495da9bca01fbe9bd6534c33688ce8846c8c32165184#npm:4.3.4"],\
["js-yaml", "npm:4.1.0"],\
["lodash", "npm:4.17.21"],\
["minimatch", "npm:3.1.2"],\
["yup", "npm:0.32.11"]\
],\
"linkType": "HARD"\
}]\
]],\
["@verdaccio/core", [\
["npm:6.0.0-6-next.55", {\
"packageLocation": "./.yarn/cache/@verdaccio-core-npm-6.0.0-6-next.55-35143ffa02-91252d8cf2.zip/node_modules/@verdaccio/core/",\
["npm:6.0.0-6-next.60", {\
"packageLocation": "./.yarn/cache/@verdaccio-core-npm-6.0.0-6-next.60-2d2b64aa8a-059d6e906c.zip/node_modules/@verdaccio/core/",\
"packageDependencies": [\
["@verdaccio/core", "npm:6.0.0-6-next.55"],\
["@verdaccio/core", "npm:6.0.0-6-next.60"],\
["ajv", "npm:8.11.2"],\
["core-js", "npm:3.27.0"],\
["http-errors", "npm:1.8.1"],\
@ -4526,10 +4516,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
],\
"linkType": "HARD"\
}],\
["npm:6.0.0-6-next.59", {\
"packageLocation": "./.yarn/cache/@verdaccio-core-npm-6.0.0-6-next.59-665d4ea448-f680d05284.zip/node_modules/@verdaccio/core/",\
["npm:6.0.0-6-next.61", {\
"packageLocation": "./.yarn/cache/@verdaccio-core-npm-6.0.0-6-next.61-0907cdc744-841300b390.zip/node_modules/@verdaccio/core/",\
"packageDependencies": [\
["@verdaccio/core", "npm:6.0.0-6-next.59"],\
["@verdaccio/core", "npm:6.0.0-6-next.61"],\
["ajv", "npm:8.11.2"],\
["core-js", "npm:3.27.0"],\
["http-errors", "npm:1.8.1"],\
@ -4568,22 +4558,22 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["@verdaccio/logger-7", [\
["npm:6.0.0-6-next.4", {\
"packageLocation": "./.yarn/cache/@verdaccio-logger-7-npm-6.0.0-6-next.4-60dd44100a-cd818b49b6.zip/node_modules/@verdaccio/logger-7/",\
["npm:6.0.0-6-next.6", {\
"packageLocation": "./.yarn/cache/@verdaccio-logger-7-npm-6.0.0-6-next.6-7d72475a50-1dd6ae246f.zip/node_modules/@verdaccio/logger-7/",\
"packageDependencies": [\
["@verdaccio/logger-7", "npm:6.0.0-6-next.4"],\
["@verdaccio/logger-commons", "npm:6.0.0-6-next.27"],\
["@verdaccio/logger-7", "npm:6.0.0-6-next.6"],\
["@verdaccio/logger-commons", "npm:6.0.0-6-next.29"],\
["pino", "npm:7.11.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["@verdaccio/logger-commons", [\
["npm:6.0.0-6-next.27", {\
"packageLocation": "./.yarn/cache/@verdaccio-logger-commons-npm-6.0.0-6-next.27-acca07a66a-6970924e11.zip/node_modules/@verdaccio/logger-commons/",\
["npm:6.0.0-6-next.29", {\
"packageLocation": "./.yarn/cache/@verdaccio-logger-commons-npm-6.0.0-6-next.29-f4ce59033e-d50e876d77.zip/node_modules/@verdaccio/logger-commons/",\
"packageDependencies": [\
["@verdaccio/logger-commons", "npm:6.0.0-6-next.27"],\
["@verdaccio/core", "npm:6.0.0-6-next.59"],\
["@verdaccio/logger-commons", "npm:6.0.0-6-next.29"],\
["@verdaccio/core", "npm:6.0.0-6-next.61"],\
["@verdaccio/logger-prettify", "npm:6.0.0-6-next.9"],\
["colorette", "npm:2.0.19"],\
["debug", "virtual:1eb3a4b7acf39cc06579ce173dfc189db60be09511a857cde17cd58b8e2d244d4d50cb2c180dd19733a7495da9bca01fbe9bd6534c33688ce8846c8c32165184#npm:4.3.4"]\
@ -4606,14 +4596,19 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["@verdaccio/middleware", [\
["npm:6.0.0-6-next.38", {\
"packageLocation": "./.yarn/cache/@verdaccio-middleware-npm-6.0.0-6-next.38-a734f67ca7-0899b02932.zip/node_modules/@verdaccio/middleware/",\
["npm:6.0.0-6-next.40", {\
"packageLocation": "./.yarn/cache/@verdaccio-middleware-npm-6.0.0-6-next.40-af46c692ad-29dd30c43a.zip/node_modules/@verdaccio/middleware/",\
"packageDependencies": [\
["@verdaccio/middleware", "npm:6.0.0-6-next.38"],\
["@verdaccio/core", "npm:6.0.0-6-next.59"],\
["@verdaccio/utils", "npm:6.0.0-6-next.27"],\
["@verdaccio/middleware", "npm:6.0.0-6-next.40"],\
["@verdaccio/config", "npm:6.0.0-6-next.61"],\
["@verdaccio/core", "npm:6.0.0-6-next.61"],\
["@verdaccio/url", "npm:11.0.0-6-next.27"],\
["@verdaccio/utils", "npm:6.0.0-6-next.29"],\
["debug", "virtual:1eb3a4b7acf39cc06579ce173dfc189db60be09511a857cde17cd58b8e2d244d4d50cb2c180dd19733a7495da9bca01fbe9bd6534c33688ce8846c8c32165184#npm:4.3.4"],\
["express", "npm:4.18.2"],\
["express-rate-limit", "npm:5.5.1"],\
["lodash", "npm:4.17.21"],\
["lru-cache", "npm:7.14.1"],\
["mime", "npm:2.6.0"]\
],\
"linkType": "HARD"\
@ -4629,13 +4624,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["@verdaccio/tarball", [\
["npm:11.0.0-6-next.28", {\
"packageLocation": "./.yarn/cache/@verdaccio-tarball-npm-11.0.0-6-next.28-0ba05f9f3c-89df2d15e7.zip/node_modules/@verdaccio/tarball/",\
["npm:11.0.0-6-next.30", {\
"packageLocation": "./.yarn/cache/@verdaccio-tarball-npm-11.0.0-6-next.30-5bc4fc707a-a9010fb79c.zip/node_modules/@verdaccio/tarball/",\
"packageDependencies": [\
["@verdaccio/tarball", "npm:11.0.0-6-next.28"],\
["@verdaccio/core", "npm:6.0.0-6-next.59"],\
["@verdaccio/url", "npm:11.0.0-6-next.25"],\
["@verdaccio/utils", "npm:6.0.0-6-next.27"],\
["@verdaccio/tarball", "npm:11.0.0-6-next.30"],\
["@verdaccio/core", "npm:6.0.0-6-next.61"],\
["@verdaccio/url", "npm:11.0.0-6-next.27"],\
["@verdaccio/utils", "npm:6.0.0-6-next.29"],\
["debug", "virtual:1eb3a4b7acf39cc06579ce173dfc189db60be09511a857cde17cd58b8e2d244d4d50cb2c180dd19733a7495da9bca01fbe9bd6534c33688ce8846c8c32165184#npm:4.3.4"],\
["lodash", "npm:4.17.21"]\
],\
@ -4652,20 +4647,20 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["@verdaccio/ui-theme", [\
["npm:6.0.0-6-next.59", {\
"packageLocation": "./.yarn/cache/@verdaccio-ui-theme-npm-6.0.0-6-next.59-c2a3c7ccb1-63ffe70e93.zip/node_modules/@verdaccio/ui-theme/",\
["npm:3.4.1", {\
"packageLocation": "./.yarn/cache/@verdaccio-ui-theme-npm-3.4.1-ff9f347e40-9d1fd69bf2.zip/node_modules/@verdaccio/ui-theme/",\
"packageDependencies": [\
["@verdaccio/ui-theme", "npm:6.0.0-6-next.59"]\
["@verdaccio/ui-theme", "npm:3.4.1"]\
],\
"linkType": "HARD"\
}]\
]],\
["@verdaccio/url", [\
["npm:11.0.0-6-next.25", {\
"packageLocation": "./.yarn/cache/@verdaccio-url-npm-11.0.0-6-next.25-4c823ce3f8-612aef35b7.zip/node_modules/@verdaccio/url/",\
["npm:11.0.0-6-next.27", {\
"packageLocation": "./.yarn/cache/@verdaccio-url-npm-11.0.0-6-next.27-512a73264c-e89d4477bb.zip/node_modules/@verdaccio/url/",\
"packageDependencies": [\
["@verdaccio/url", "npm:11.0.0-6-next.25"],\
["@verdaccio/core", "npm:6.0.0-6-next.59"],\
["@verdaccio/url", "npm:11.0.0-6-next.27"],\
["@verdaccio/core", "npm:6.0.0-6-next.61"],\
["debug", "virtual:1eb3a4b7acf39cc06579ce173dfc189db60be09511a857cde17cd58b8e2d244d4d50cb2c180dd19733a7495da9bca01fbe9bd6534c33688ce8846c8c32165184#npm:4.3.4"],\
["lodash", "npm:4.17.21"],\
["validator", "npm:13.7.0"]\
@ -4674,22 +4669,22 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["@verdaccio/utils", [\
["npm:6.0.0-6-next.23", {\
"packageLocation": "./.yarn/cache/@verdaccio-utils-npm-6.0.0-6-next.23-c9d31b3408-33f250c6df.zip/node_modules/@verdaccio/utils/",\
["npm:6.0.0-6-next.28", {\
"packageLocation": "./.yarn/cache/@verdaccio-utils-npm-6.0.0-6-next.28-c868bd3942-cea635e77c.zip/node_modules/@verdaccio/utils/",\
"packageDependencies": [\
["@verdaccio/utils", "npm:6.0.0-6-next.23"],\
["@verdaccio/core", "npm:6.0.0-6-next.55"],\
["@verdaccio/utils", "npm:6.0.0-6-next.28"],\
["@verdaccio/core", "npm:6.0.0-6-next.60"],\
["lodash", "npm:4.17.21"],\
["minimatch", "npm:3.1.2"],\
["semver", "npm:7.3.8"]\
],\
"linkType": "HARD"\
}],\
["npm:6.0.0-6-next.27", {\
"packageLocation": "./.yarn/cache/@verdaccio-utils-npm-6.0.0-6-next.27-f0803abfd2-33144003ab.zip/node_modules/@verdaccio/utils/",\
["npm:6.0.0-6-next.29", {\
"packageLocation": "./.yarn/cache/@verdaccio-utils-npm-6.0.0-6-next.29-02707032e1-ee5c55b986.zip/node_modules/@verdaccio/utils/",\
"packageDependencies": [\
["@verdaccio/utils", "npm:6.0.0-6-next.27"],\
["@verdaccio/core", "npm:6.0.0-6-next.59"],\
["@verdaccio/utils", "npm:6.0.0-6-next.29"],\
["@verdaccio/core", "npm:6.0.0-6-next.61"],\
["lodash", "npm:4.17.21"],\
["minimatch", "npm:3.1.2"],\
["semver", "npm:7.3.8"]\
@ -10756,10 +10751,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["node-fetch", [\
["npm:2.6.8", {\
"packageLocation": "./.yarn/cache/node-fetch-npm-2.6.8-ddb8bfc274-91f57be68e.zip/node_modules/node-fetch/",\
["npm:2.6.7", {\
"packageLocation": "./.yarn/cache/node-fetch-npm-2.6.7-777aa2a6df-8d816ffd1e.zip/node_modules/node-fetch/",\
"packageDependencies": [\
["node-fetch", "npm:2.6.8"]\
["node-fetch", "npm:2.6.7"]\
],\
"linkType": "SOFT"\
}],\
@ -10784,10 +10779,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
],\
"linkType": "HARD"\
}],\
["virtual:725618ea2a18976bd37b5650a38a9389d1a204d1c52b4d955cc139672da5613553bf6d4b593ac20da00640f048f69a3ae2a8711763d2071007195c62ca216abc#npm:2.6.8", {\
"packageLocation": "./.yarn/__virtual__/node-fetch-virtual-a9082871ce/0/cache/node-fetch-npm-2.6.8-ddb8bfc274-91f57be68e.zip/node_modules/node-fetch/",\
["virtual:3db624596952c54d0f43797faed029b18df0dd118eb6a3a2066ab16f59a3ad611e6d68074f022a94e833bcb6b0bb398b6cfd64ea470afea866b835f8060967c3#npm:2.6.7", {\
"packageLocation": "./.yarn/__virtual__/node-fetch-virtual-c106191fe7/0/cache/node-fetch-npm-2.6.7-777aa2a6df-8d816ffd1e.zip/node_modules/node-fetch/",\
"packageDependencies": [\
["node-fetch", "virtual:725618ea2a18976bd37b5650a38a9389d1a204d1c52b4d955cc139672da5613553bf6d4b593ac20da00640f048f69a3ae2a8711763d2071007195c62ca216abc#npm:2.6.8"],\
["node-fetch", "virtual:3db624596952c54d0f43797faed029b18df0dd118eb6a3a2066ab16f59a3ad611e6d68074f022a94e833bcb6b0bb398b6cfd64ea470afea866b835f8060967c3#npm:2.6.7"],\
["@types/encoding", null],\
["encoding", null],\
["whatwg-url", "npm:5.0.0"]\
@ -13476,7 +13471,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["@trivago/prettier-plugin-sort-imports", "virtual:7f7b3df50ee4b7b1719ad19fad11505dc2788f3227a7e5cc9ca19f71d8cb309c9d33b532ea2b2b60ab65abf6cc12153df4643c5e6e17d01ea0ae0492723bb4b4#npm:4.0.0"],\
["@types/async", "npm:3.2.16"],\
["@types/express", "npm:4.17.14"],\
["@types/express-rate-limit", "npm:5.1.3"],\
["@types/express-serve-static-core", "npm:4.17.28"],\
["@types/http-errors", "npm:2.0.1"],\
["@types/jest", "npm:26.0.24"],\
@ -13490,17 +13484,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["@typescript-eslint/eslint-plugin", "virtual:7f7b3df50ee4b7b1719ad19fad11505dc2788f3227a7e5cc9ca19f71d8cb309c9d33b532ea2b2b60ab65abf6cc12153df4643c5e6e17d01ea0ae0492723bb4b4#npm:5.49.0"],\
["@typescript-eslint/parser", "virtual:7f7b3df50ee4b7b1719ad19fad11505dc2788f3227a7e5cc9ca19f71d8cb309c9d33b532ea2b2b60ab65abf6cc12153df4643c5e6e17d01ea0ae0492723bb4b4#npm:5.49.0"],\
["@verdaccio-scope/verdaccio-auth-foo", "npm:0.0.2"],\
["@verdaccio/config", "npm:6.0.0-6-next.55"],\
["@verdaccio/core", "npm:6.0.0-6-next.59"],\
["@verdaccio/config", "npm:6.0.0-6-next.61"],\
["@verdaccio/core", "npm:6.0.0-6-next.61"],\
["@verdaccio/local-storage", "npm:10.3.1"],\
["@verdaccio/logger-7", "npm:6.0.0-6-next.4"],\
["@verdaccio/middleware", "npm:6.0.0-6-next.38"],\
["@verdaccio/logger-7", "npm:6.0.0-6-next.6"],\
["@verdaccio/middleware", "npm:6.0.0-6-next.40"],\
["@verdaccio/streams", "npm:10.2.0"],\
["@verdaccio/tarball", "npm:11.0.0-6-next.28"],\
["@verdaccio/tarball", "npm:11.0.0-6-next.30"],\
["@verdaccio/types", "npm:10.7.0"],\
["@verdaccio/ui-theme", "npm:6.0.0-6-next.59"],\
["@verdaccio/url", "npm:11.0.0-6-next.25"],\
["@verdaccio/utils", "npm:6.0.0-6-next.27"],\
["@verdaccio/ui-theme", "npm:3.4.1"],\
["@verdaccio/url", "npm:11.0.0-6-next.27"],\
["@verdaccio/utils", "npm:6.0.0-6-next.29"],\
["JSONStream", "npm:1.3.5"],\
["async", "npm:3.2.4"],\
["babel-eslint", "virtual:7f7b3df50ee4b7b1719ad19fad11505dc2788f3227a7e5cc9ca19f71d8cb309c9d33b532ea2b2b60ab65abf6cc12153df4643c5e6e17d01ea0ae0492723bb4b4#npm:10.1.0"],\
@ -13525,7 +13519,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["eslint-plugin-simple-import-sort", "virtual:7f7b3df50ee4b7b1719ad19fad11505dc2788f3227a7e5cc9ca19f71d8cb309c9d33b532ea2b2b60ab65abf6cc12153df4643c5e6e17d01ea0ae0492723bb4b4#npm:9.0.0"],\
["eslint-plugin-verdaccio", "npm:10.0.0"],\
["express", "npm:4.18.2"],\
["express-rate-limit", "npm:5.5.1"],\
["fast-safe-stringify", "npm:2.1.1"],\
["fs-extra", "npm:10.1.0"],\
["get-port", "npm:5.1.1"],\
@ -13541,7 +13534,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["lint-staged", "npm:11.0.1"],\
["lockfile-lint", "npm:4.6.2"],\
["lodash", "npm:4.17.21"],\
["lru-cache", "npm:7.14.1"],\
["lunr-mutable-indexes", "npm:2.3.2"],\
["mime", "npm:3.0.0"],\
["mkdirp", "npm:1.0.4"],\
@ -13560,7 +13552,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["ts-node", "virtual:7f7b3df50ee4b7b1719ad19fad11505dc2788f3227a7e5cc9ca19f71d8cb309c9d33b532ea2b2b60ab65abf6cc12153df4643c5e6e17d01ea0ae0492723bb4b4#npm:10.9.1"],\
["typescript", "patch:typescript@npm%3A4.1.3#~builtin<compat/typescript>::version=4.1.3&hash=4a8eb8"],\
["validator", "npm:13.7.0"],\
["verdaccio-audit", "npm:10.2.4"],\
["verdaccio-audit", "npm:11.0.0-6-next.23"],\
["verdaccio-auth-memory", "npm:10.2.0"],\
["verdaccio-htpasswd", "npm:10.5.2"],\
["verdaccio-memory", "npm:10.3.0"]\
@ -13569,14 +13561,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
}]\
]],\
["verdaccio-audit", [\
["npm:10.2.4", {\
"packageLocation": "./.yarn/cache/verdaccio-audit-npm-10.2.4-725618ea2a-7fccea4371.zip/node_modules/verdaccio-audit/",\
["npm:11.0.0-6-next.23", {\
"packageLocation": "./.yarn/cache/verdaccio-audit-npm-11.0.0-6-next.23-3db6245969-3c07ee4aaf.zip/node_modules/verdaccio-audit/",\
"packageDependencies": [\
["verdaccio-audit", "npm:10.2.4"],\
["body-parser", "npm:1.20.1"],\
["verdaccio-audit", "npm:11.0.0-6-next.23"],\
["@verdaccio/config", "npm:6.0.0-6-next.60"],\
["@verdaccio/core", "npm:6.0.0-6-next.60"],\
["express", "npm:4.18.2"],\
["https-proxy-agent", "npm:5.0.1"],\
["node-fetch", "virtual:725618ea2a18976bd37b5650a38a9389d1a204d1c52b4d955cc139672da5613553bf6d4b593ac20da00640f048f69a3ae2a8711763d2071007195c62ca216abc#npm:2.6.8"]\
["node-fetch", "virtual:3db624596952c54d0f43797faed029b18df0dd118eb6a3a2066ab16f59a3ad611e6d68074f022a94e833bcb6b0bb398b6cfd64ea470afea866b835f8060967c3#npm:2.6.7"]\
],\
"linkType": "HARD"\
}]\

Binary file not shown.

Binary file not shown.

View file

@ -4,6 +4,10 @@ enableGlobalCache: false
npmRegistryServer: "https://registry.npmjs.org"
# npmRegistryServer: "http://localhost:4873/"
# unsafeHttpWhitelist:
# - localhost
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
spec: "@yarnpkg/plugin-workspace-tools"

View file

@ -1,4 +1,4 @@
FROM --platform=${BUILDPLATFORM:-linux/amd64} node:18.13.0-alpine as builder
FROM --platform=${BUILDPLATFORM:-linux/amd64} node:18.14.0-alpine as builder
ENV NODE_ENV=production \
VERDACCIO_BUILD_REGISTRY=https://registry.npmjs.org \
@ -21,7 +21,7 @@ COPY . .
RUN yarn config set npmRegistryServer $VERDACCIO_BUILD_REGISTRY && \
yarn config set enableProgressBars true && \
yarn config set enableScripts false && \
yarn install && \
yarn install --immutable && \
yarn build
## pack the project
RUN yarn pack --out verdaccio.tgz \
@ -30,7 +30,7 @@ RUN yarn pack --out verdaccio.tgz \
## clean up and reduce bundle size
RUN rm -Rf /opt/verdaccio-build
FROM node:18.13.0-alpine
FROM node:18.14.0-alpine
LABEL maintainer="https://github.com/verdaccio/verdaccio"
ENV VERDACCIO_APPDIR=/opt/verdaccio \

View file

@ -19,16 +19,16 @@
"url": "https://opencollective.com/verdaccio"
},
"dependencies": {
"@verdaccio/config": "6.0.0-6-next.55",
"@verdaccio/core": "6.0.0-6-next.59",
"@verdaccio/config": "6.0.0-6-next.61",
"@verdaccio/core": "6.0.0-6-next.61",
"@verdaccio/local-storage": "10.3.1",
"@verdaccio/logger-7": "6.0.0-6-next.4",
"@verdaccio/middleware": "6.0.0-6-next.38",
"@verdaccio/logger-7": "6.0.0-6-next.6",
"@verdaccio/middleware": "6.0.0-6-next.40",
"@verdaccio/streams": "10.2.0",
"@verdaccio/tarball": "11.0.0-6-next.28",
"@verdaccio/ui-theme": "6.0.0-6-next.59",
"@verdaccio/url": "11.0.0-6-next.25",
"@verdaccio/utils": "6.0.0-6-next.27",
"@verdaccio/tarball": "11.0.0-6-next.30",
"@verdaccio/ui-theme": "3.4.1",
"@verdaccio/url": "11.0.0-6-next.27",
"@verdaccio/utils": "6.0.0-6-next.29",
"JSONStream": "1.3.5",
"async": "3.2.4",
"body-parser": "1.20.1",
@ -39,14 +39,12 @@
"debug": "^4.3.4",
"envinfo": "7.8.1",
"express": "4.18.2",
"express-rate-limit": "5.5.1",
"fast-safe-stringify": "2.1.1",
"handlebars": "4.7.7",
"js-yaml": "4.1.0",
"jsonwebtoken": "9.0.0",
"kleur": "4.1.5",
"lodash": "4.17.21",
"lru-cache": "7.14.1",
"lunr-mutable-indexes": "2.3.2",
"mime": "3.0.0",
"mkdirp": "1.0.4",
@ -55,7 +53,7 @@
"request": "2.88.0",
"semver": "7.3.8",
"validator": "13.7.0",
"verdaccio-audit": "10.2.4",
"verdaccio-audit": "11.0.0-6-next.23",
"verdaccio-htpasswd": "10.5.2"
},
"devDependencies": {
@ -86,7 +84,6 @@
"@trivago/prettier-plugin-sort-imports": "4.0.0",
"@types/async": "3.2.16",
"@types/express": "4.17.14",
"@types/express-rate-limit": "5.1.3",
"@types/express-serve-static-core": "4.17.28",
"@types/http-errors": "2.0.1",
"@types/jest": "26.0.24",
@ -151,6 +148,7 @@
"scripts": {
"release": "standard-version -a -s",
"type-check": "tsc --noEmit",
"cache:clean": "yarn cache clean --mirror && yarn cache clean --all",
"type-check:watch": "yarn run type-check -- --watch",
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,yml,yaml,md}\"",
"format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,yml,yaml,md}\"",
@ -191,13 +189,5 @@
"url": "https://opencollective.com/verdaccio",
"logo": "https://opencollective.com/verdaccio/logo.txt"
},
"packageManager": "yarn@3.3.1",
"dependenciesMeta": {
"@verdaccio/logger-7@6.0.0-6-next.3": {
"unplugged": true
},
"jest@29.3.1": {
"unplugged": true
}
}
"packageManager": "yarn@3.3.1"
}

View file

@ -2,6 +2,7 @@ import Cookies from 'cookies';
import express, { Response, Router } from 'express';
import _ from 'lodash';
import { rateLimit } from '@verdaccio/middleware';
import { Config, RemoteUser } from '@verdaccio/types';
import { createSessionToken, getAuthenticatedMessage } from '@verdaccio/utils';
@ -10,7 +11,6 @@ import { API_ERROR, API_MESSAGE, HEADERS, HTTP_STATUS } from '../../../lib/const
import { logger } from '../../../lib/logger';
import { ErrorCode } from '../../../lib/utils';
import { $NextFunctionVer, $RequestExtend, $ResponseExtend, IAuth } from '../../../types';
import { limiter } from '../../rate-limiter';
export default function (route: Router, auth: IAuth, config: Config): void {
/* eslint new-cap:off */
@ -18,7 +18,7 @@ export default function (route: Router, auth: IAuth, config: Config): void {
userRouter.get(
'/-/user/:org_couchdb_user',
limiter(config?.userRateLimit),
rateLimit(config?.userRateLimit),
function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
res.status(HTTP_STATUS.OK);
next({
@ -29,7 +29,7 @@ export default function (route: Router, auth: IAuth, config: Config): void {
userRouter.put(
'/-/user/:org_couchdb_user/:_rev?/:revision?',
limiter(config?.userRateLimit),
rateLimit(config?.userRateLimit),
function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
const { name, password } = req.body;
const remoteName = req.remote_user.name;
@ -96,7 +96,7 @@ export default function (route: Router, auth: IAuth, config: Config): void {
userRouter.delete(
'/-/user/token/*',
limiter(config?.userRateLimit),
rateLimit(config?.userRateLimit),
function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
res.status(HTTP_STATUS.OK);
next({

View file

@ -1,11 +1,12 @@
import { Response, Router } from 'express';
import _ from 'lodash';
import { rateLimit } from '@verdaccio/middleware';
import { validatePassword } from '../../../../lib/auth-utils';
import { API_ERROR, APP_ERROR, HTTP_STATUS, SUPPORT_ERRORS } from '../../../../lib/constants';
import { ErrorCode } from '../../../../lib/utils';
import { $NextFunctionVer, $RequestExtend, IAuth } from '../../../../types';
import { limiter } from '../../../rate-limiter';
export interface Profile {
tfa: boolean;
@ -35,7 +36,7 @@ export default function (auth: IAuth, config): Router {
profileRoute.get(
'/user',
limiter(config?.userRateLimit),
rateLimit(config?.userRateLimit),
function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
if (_.isNil(req.remote_user.name) === false) {
return next(buildProfile(req.remote_user.name));
@ -50,7 +51,7 @@ export default function (auth: IAuth, config): Router {
profileRoute.post(
'/user',
limiter(config?.userRateLimit),
rateLimit(config?.userRateLimit),
function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
if (_.isNil(req.remote_user.name)) {
res.status(HTTP_STATUS.UNAUTHORIZED);

View file

@ -2,6 +2,7 @@ import buildDebug from 'debug';
import { Response, Router } from 'express';
import _ from 'lodash';
import { rateLimit } from '@verdaccio/middleware';
import { Config, RemoteUser, Token } from '@verdaccio/types';
import { stringToMD5 } from '@verdaccio/utils';
@ -10,7 +11,6 @@ import { HEADERS, HTTP_STATUS, SUPPORT_ERRORS } from '../../../../lib/constants'
import { logger } from '../../../../lib/logger';
import { ErrorCode, mask } from '../../../../lib/utils';
import { $NextFunctionVer, $RequestExtend, IAuth, IStorageHandler } from '../../../../types';
import { limiter } from '../../../rate-limiter';
const debug = buildDebug('verdaccio:token');
export type NormalizeToken = Token & {
@ -29,7 +29,7 @@ export default function (auth: IAuth, storage: IStorageHandler, config: Config):
const tokenRoute = Router(); /* eslint new-cap: 0 */
tokenRoute.get(
'/tokens',
limiter(config?.userRateLimit),
rateLimit(config?.userRateLimit),
async function (req: $RequestExtend, res: Response, next: $NextFunctionVer) {
const { name } = req.remote_user;
@ -56,7 +56,7 @@ export default function (auth: IAuth, storage: IStorageHandler, config: Config):
tokenRoute.post(
'/tokens',
limiter(config?.userRateLimit),
rateLimit(config?.userRateLimit),
function (req: $RequestExtend, res: Response, next: $NextFunctionVer) {
const { password, readonly, cidr_whitelist } = req.body;
const { name } = req.remote_user;
@ -122,7 +122,7 @@ export default function (auth: IAuth, storage: IStorageHandler, config: Config):
tokenRoute.delete(
'/tokens/token/:tokenKey',
limiter(config?.userRateLimit),
rateLimit(config?.userRateLimit),
async (req: $RequestExtend, res: Response, next: $NextFunctionVer) => {
const {
params: { tokenKey },

View file

@ -1,4 +1,3 @@
import bodyParser from 'body-parser';
import express from 'express';
import { Config } from '@verdaccio/types';
@ -42,7 +41,7 @@ export default function (config: Config, auth: IAuth, storage: IStorageHandler)
app.param('org_couchdb_user', match(/^org\.couchdb\.user:/));
app.use(auth.apiJWTmiddleware());
app.use(bodyParser.json({ strict: false, limit: config.max_body_size || '10mb' }));
app.use(express.json({ strict: false, limit: config.max_body_size || '10mb' }));
app.use(antiLoop(config));
// encode / in a scoped package name to be matched as a single parameter in routes
app.use(encodeScopePackage);

View file

@ -3,6 +3,7 @@ import cors from 'cors';
import express, { Application } from 'express';
import _ from 'lodash';
import { getUserAgent } from '@verdaccio/config';
import { final } from '@verdaccio/middleware';
import { log } from '@verdaccio/middleware';
import { Config as IConfig, IPluginMiddleware, IPluginStorageFilter } from '@verdaccio/types';
@ -13,7 +14,7 @@ import { API_ERROR } from '../lib/constants';
import { logger, setup } from '../lib/logger';
import loadPlugin from '../lib/plugin-loader';
import Storage from '../lib/storage';
import { ErrorCode, getUserAgent } from '../lib/utils';
import { ErrorCode } from '../lib/utils';
import {
$NextFunctionVer,
$RequestExtend,
@ -24,8 +25,23 @@ import {
import hookDebug from './debug';
import apiEndpoint from './endpoint';
import { errorReportingMiddleware, handleError, serveFavicon } from './middleware';
import web from './web';
import webAPI from './web/api';
import webMiddleware from './web';
export function loadTheme(config) {
if (_.isNil(config.theme) === false) {
return _.head(
loadPlugin(
config,
config.theme,
{},
function (plugin) {
return plugin.staticPath && plugin.manifest && plugin.manifestFiles;
},
'verdaccio-theme'
)
);
}
}
const defineAPI = function (config: IConfig, storage: IStorageHandler): any {
const auth: IAuth = new Auth(config);
@ -87,8 +103,7 @@ const defineAPI = function (config: IConfig, storage: IStorageHandler): any {
// For WebUI & WebUI API
if (_.get(config, 'web.enable', true)) {
app.use('/', web(config, auth, storage));
app.use('/-/verdaccio/', webAPI(config, auth, storage));
app.use('/', webMiddleware(config, auth, storage));
} else {
app.get('/', function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
next(ErrorCode.getNotFound(API_ERROR.WEB_DISABLED));

View file

@ -1,12 +0,0 @@
import RateLimit from 'express-rate-limit';
import { RateLimit as RateLimitType } from '@verdaccio/types';
const limiter = (rateLimitOptions: RateLimitType) => {
// @ts-ignore
return new RateLimit({
...rateLimitOptions,
});
};
export { limiter };

View file

@ -1,29 +0,0 @@
import bodyParser from 'body-parser';
import { Router } from 'express';
import { setSecurityWebHeaders, validateName, validatePackage } from '@verdaccio/middleware';
import { Config } from '@verdaccio/types';
import Search from '../../lib/search';
import { IAuth, IStorageHandler } from '../../types';
import webApi from './endpoint';
const route = Router(); /* eslint new-cap: 0 */
/*
This file include all verdaccio only API(Web UI), for npm API please see ../endpoint/
*/
export default function (config: Config, auth: IAuth, storage: IStorageHandler): Router {
Search.configureStorage(storage);
// validate all of these params as a package name
// this might be too harsh, so ask if it causes trouble
route.param('package', validatePackage);
route.param('filename', validateName);
route.param('version', validateName);
route.use(bodyParser.urlencoded({ extended: false }));
route.use(auth.webUIJWTmiddleware());
route.use(setSecurityWebHeaders);
route.use(webApi(auth, storage, config));
return route;
}

View file

@ -1,7 +1,8 @@
import { Response, Router } from 'express';
import { Router } from 'express';
import { rateLimit } from '@verdaccio/middleware';
import { hasLogin } from '../../../lib/utils';
import { limiter } from '../../rate-limiter';
import packageApi from './package';
import search from './search';
import user from './user';
@ -10,7 +11,7 @@ export default (auth, storage, config) => {
const route = Router(); /* eslint new-cap: 0 */
route.use(
'/data/',
limiter({
rateLimit({
windowMs: 2 * 60 * 1000, // 2 minutes
max: 5000, // limit each IP to 1000 requests per windowMs
...config?.web?.rateLimit,
@ -18,7 +19,7 @@ export default (auth, storage, config) => {
);
route.use('/data/', packageApi(storage, auth, config));
route.use('/data/', search(storage, auth));
route.use('/sec/', limiter(config?.userRateLimit));
route.use('/sec/', rateLimit(config?.userRateLimit));
if (hasLogin(config)) {
route.use('/sec/', user(auth, storage));
}

View file

@ -1,23 +0,0 @@
import buildDebug from 'debug';
export type Manifest = {
// goes on first place at the header
ico: string;
css: string[];
js: string[];
};
const debug = buildDebug('verdaccio');
export function getManifestValue(
manifestItems: string[],
manifest,
basePath: string = ''
): string[] {
return manifestItems?.map((item) => {
debug('resolve item %o', item);
const resolvedItem = `${basePath}${manifest[item]}`;
debug('resolved item %o', resolvedItem);
return resolvedItem;
});
}

View file

@ -1,133 +0,0 @@
import buildDebug from 'debug';
import LRU from 'lru-cache';
import path from 'path';
import { URL } from 'url';
import { HEADERS } from '@verdaccio/core';
import { getPublicUrl } from '@verdaccio/url';
import { WEB_TITLE } from '../../../lib/constants';
import { hasLogin, isHTTPProtocol } from '../../../lib/utils';
import renderTemplate from './template';
const pkgJSON = require('../../../../package.json');
const DEFAULT_LANGUAGE = 'es-US';
const cache = new LRU({ max: 500, ttl: 1000 * 60 * 60 });
const debug = buildDebug('verdaccio');
const defaultManifestFiles = {
js: ['runtime.js', 'vendors.js', 'main.js'],
ico: 'favicon.ico',
};
export function validatePrimaryColor(primaryColor) {
const isHex = /^#+([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/i.test(primaryColor);
if (!isHex) {
debug('invalid primary color %o', primaryColor);
return;
}
return primaryColor;
}
export function resolveLogo(config, req) {
const isLocalFile = config?.web?.logo && !isHTTPProtocol(config?.web?.logo);
if (isLocalFile) {
return `${getPublicUrl(config?.url_prefix, req)}-/static/${path.basename(config?.web?.logo)}`;
} else if (isHTTPProtocol(config?.web?.logo)) {
return config?.web?.logo;
} else {
return '';
}
}
export default function renderHTML(config, manifest, manifestFiles, req, res) {
const { url_prefix } = config;
const base = getPublicUrl(config?.url_prefix, req);
const basename = new URL(base).pathname;
const language = config?.i18n?.web ?? DEFAULT_LANGUAGE;
const needHtmlCache = [undefined, null].includes(config?.web?.html_cache)
? true
: config.web.html_cache;
const darkMode = config?.web?.darkMode ?? false;
const title = config?.web?.title ?? WEB_TITLE;
const scope = config?.web?.scope ?? '';
const login = hasLogin(config);
const logoURI = resolveLogo(config, req);
const pkgManagers = config?.web?.pkgManagers ?? ['yarn', 'pnpm', 'npm'];
const version = pkgJSON.version;
const primaryColor = validatePrimaryColor(config?.web?.primary_color) ?? '#4b5e40';
const {
scriptsBodyAfter,
metaScripts,
scriptsbodyBefore,
showInfo,
showSettings,
showThemeSwitch,
showFooter,
showSearch,
showDownloadTarball,
} = Object.assign(
{},
{
scriptsBodyAfter: [],
bodyBefore: [],
metaScripts: [],
},
config?.web
);
const options = {
showInfo,
showSettings,
showThemeSwitch,
showFooter,
showSearch,
showDownloadTarball,
darkMode,
url_prefix,
basename,
base,
primaryColor,
version,
pkgManagers,
login,
logo: logoURI,
title,
scope,
language,
};
let webPage;
try {
webPage = cache.get('template');
if (!webPage) {
debug('web options %o', options);
debug('web manifestFiles %o', manifestFiles);
webPage = renderTemplate(
{
manifest: manifestFiles ?? defaultManifestFiles,
options,
scriptsBodyAfter,
metaScripts,
scriptsbodyBefore,
},
manifest
);
debug('template :: %o', webPage);
if (needHtmlCache) {
cache.set('template', webPage);
debug('set template cache');
}
} else {
debug('reuse template cache');
}
} catch (error) {
throw new Error(`theme could not be load, stack ${error.stack}`);
}
res.setHeader('Content-Type', HEADERS.TEXT_HTML);
res.send(webPage);
debug('render web');
}

View file

@ -1,63 +0,0 @@
import buildDebug from 'debug';
import { Manifest, getManifestValue } from './manifest';
const debug = buildDebug('verdaccio');
export type TemplateUIOptions = {
title?: string;
uri?: string;
darkMode?: boolean;
protocol?: string;
host?: string;
url_prefix?: string;
base: string;
primaryColor?: string;
version?: string;
logoURI?: string;
scope?: string;
language?: string;
};
export type Template = {
manifest: Manifest;
options: TemplateUIOptions;
metaScripts?: string[];
scriptsBodyAfter?: string[];
scriptsbodyBefore?: string[];
};
// the outcome of the Webpack Manifest Plugin
export interface WebpackManifest {
[key: string]: string;
}
export default function renderTemplate(template: Template, manifest: WebpackManifest) {
debug('template %o', template);
debug('manifest %o', manifest);
return `
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<base href="${template?.options.base}">
<title>${template?.options?.title ?? ''}</title>
<link rel="icon" href="${template?.options.base}-/static/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script>
window.__VERDACCIO_BASENAME_UI_OPTIONS=${JSON.stringify(template.options)}
</script>
${template?.metaScripts ? template.metaScripts.join('') : ''}
</head>
<body class="body">
${template?.scriptsbodyBefore ? template.scriptsbodyBefore.join('') : ''}
<div id="root"></div>
${getManifestValue(template.manifest.js, manifest, template?.options.base)
.map((item) => `<script defer="defer" src="${item}"></script>`)
.join('')}
${template?.scriptsBodyAfter ? template.scriptsBodyAfter.join('') : ''}
</body>
</html>
`;
}

View file

@ -1,21 +1,14 @@
import buildDebug from 'debug';
import express from 'express';
import fs from 'fs';
import _ from 'lodash';
import path from 'path';
import { Config } from '@verdaccio/types';
import { webMiddleware } from '@verdaccio/middleware';
import { HTTP_STATUS } from '../../lib/constants';
import { logger } from '../../lib/logger';
import loadPlugin from '../../lib/plugin-loader';
import Search from '../../lib/search';
import { isHTTPProtocol } from '../../lib/utils';
import renderHTML from './html/renderHTML';
import webApi from './api';
const { setSecurityWebHeaders } = require('@verdaccio/middleware');
const debug = buildDebug('verdaccio');
const debug = buildDebug('verdaccio:web');
export function loadTheme(config) {
if (_.isNil(config.theme) === false) {
@ -33,88 +26,21 @@ export function loadTheme(config) {
}
}
export function validatePrimaryColor(primaryColor) {
const isHex = /^#+([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/i.test(primaryColor);
if (!isHex) {
debug('invalid primary color %o', primaryColor);
return;
}
return primaryColor;
}
const sendFileCallback = (next) => (err) => {
if (!err) {
return;
}
if (err.status === HTTP_STATUS.NOT_FOUND) {
next();
} else {
next(err);
}
};
export default function (config: Config, auth, storage) {
let { staticPath, manifest, manifestFiles } =
loadTheme(config) || require('@verdaccio/ui-theme')();
debug('static path %o', staticPath);
export default (config, auth, storage) => {
const pluginOptions = loadTheme(config) || require('@verdaccio/ui-theme')();
Search.configureStorage(storage);
/* eslint new-cap:off */
// eslint-disable-next-line new-cap
const router = express.Router();
// run in production mode by default, just in case
// it shouldn't make any difference anyway
router.use(auth.webUIJWTmiddleware());
router.use(setSecurityWebHeaders);
// static assets
router.get('/-/static/*', function (req, res, next) {
const filename = req.params[0];
const file = `${staticPath}/${filename}`;
debug('render static file %o', file);
res.sendFile(file, sendFileCallback(next));
});
// logo
if (config?.web?.logo && !isHTTPProtocol(config?.web?.logo)) {
// URI related to a local file
const absoluteLocalFile = path.posix.resolve(config.web.logo);
debug('serve local logo %s', absoluteLocalFile);
try {
if (
fs.existsSync(absoluteLocalFile) &&
typeof fs.accessSync(absoluteLocalFile, fs.constants.R_OK) === 'undefined'
) {
// Note: `path.join` will break on Windows, because it transforms `/` to `\`
// Use POSIX version `path.posix.join` instead.
config.web.logo = path.posix.join('/-/static/', path.basename(config.web.logo));
router.get(config.web.logo, function (_req, res, next) {
// @ts-ignore
debug('serve custom logo web:%s - local:%s', config.web.logo, absoluteLocalFile);
res.sendFile(absoluteLocalFile, sendFileCallback(next));
});
debug('enabled custom logo %s', config.web.logo);
} else {
config.web.logo = undefined;
logger.warn(
`web logo is wrong, path ${absoluteLocalFile} does not exist or is not readable`
);
}
} catch {
config.web.logo = undefined;
logger.warn(`web logo is wrong, path ${absoluteLocalFile} does not exist or is not readable`);
}
}
router.get('/-/web/:section/*', function (req, res) {
renderHTML(config, manifest, manifestFiles, req, res);
debug('render html section');
});
router.get('/', function (req, res, next) {
renderHTML(config, manifest, manifestFiles, req, res);
debug('render root');
});
// load application
router.use(
webMiddleware(
config,
{
tokenMiddleware: auth.webUIJWTmiddleware(),
webEndpointsApi: webApi(auth, storage, config),
},
pluginOptions
)
);
return router;
}
};

View file

@ -1,6 +1,7 @@
import assert from 'assert';
import _ from 'lodash';
import { getUserAgent } from '@verdaccio/config';
import { Config as AppConfig, Logger, PackageList, RateLimit, Security } from '@verdaccio/types';
import { generateRandomHexString, getMatchedPackagesSpec } from '@verdaccio/utils';
@ -8,7 +9,7 @@ import { MatchedPackage, StartUpConfig } from '../types';
import { defaultUserRateLimiting } from './auth-utils';
import { normalisePackageAccess, sanityCheckUplinksProps, uplinkSanityCheck } from './config-utils';
import { APP_ERROR } from './constants';
import { getUserAgent, isObject } from './utils';
import { isObject } from './utils';
const LoggerApi = require('./logger');
const strategicConfigProps = ['uplinks', 'packages'];

View file

@ -24,7 +24,7 @@ import {
import { logger } from './logger';
import { ErrorCode, isObject, isObjectOrArray, parseInterval } from './utils';
const debug = buildDebug('verdaccio:up-storage');
const debug = buildDebug('verdaccio:proxy');
const encode = function (thing): string {
return encodeURIComponent(thing).replace(/^%40/, '@');
@ -76,7 +76,7 @@ class ProxyStorage implements IProxy {
this.config = config;
this.failed_requests = 0;
// @ts-ignore
this.userAgent = mainConfig.user_agent;
this.userAgent = mainConfig.user_agent ?? 'hidden';
this.ca = config.ca;
this.logger = logger;
this.server_id = mainConfig.server_id;
@ -148,7 +148,6 @@ class ProxyStorage implements IProxy {
self.logger.info(
{
method: method,
headers: headers,
uri: uri,
},
"making request: '@{method} @{uri}'"
@ -216,7 +215,6 @@ class ProxyStorage implements IProxy {
}
}
: undefined;
let requestOptions = {
url: uri,
method: method,

View file

@ -41,28 +41,7 @@ const {
getUnauthorized,
} = errorUtils;
const debug = buildDebug('verdaccio');
// eslint-disable-next-line @typescript-eslint/no-unused-vars
// eslint-disable-next-line @typescript-eslint/no-var-requires
require('pkginfo')(module);
const pkgVersion = module.exports.version;
const pkgName = module.exports.name;
const validProtocols = ['https', 'http'];
export function getUserAgent(customUserAgent?: boolean | string): string {
assert(_.isString(pkgName));
assert(_.isString(pkgVersion));
if (customUserAgent === true) {
return `${pkgName}/${pkgVersion}`;
} else if (_.isString(customUserAgent) && _.isEmpty(customUserAgent) === false) {
return customUserAgent;
} else if (customUserAgent === false) {
return '';
}
return `${pkgName}/${pkgVersion}`;
}
export function convertPayloadToBase64(payload: string): Buffer {
return Buffer.from(payload, 'base64');
}
@ -252,25 +231,6 @@ export function parseInterval(interval: any): number {
return result;
}
/**
* Detect running protocol (http or https)
*/
export function getWebProtocol(headerProtocol: string | void, protocol: string): string {
let returnProtocol;
const [, defaultProtocol] = validProtocols;
// HAProxy variant might return http,http with X-Forwarded-Proto
if (typeof headerProtocol === 'string' && headerProtocol !== '') {
debug('header protocol: %o', protocol);
const commaIndex = headerProtocol.indexOf(',');
returnProtocol = commaIndex > 0 ? headerProtocol.substr(0, commaIndex) : headerProtocol;
} else {
debug('req protocol: %o', headerProtocol);
returnProtocol = protocol;
}
return validProtocols.includes(returnProtocol) ? returnProtocol : defaultProtocol;
}
export const ErrorCode = {
getConflict,
getBadData,
@ -451,14 +411,6 @@ export function formatAuthor(author: AuthorFormat): any {
return authorDetails;
}
/**
* Check if URI is starting with "http://", "https://" or "//"
* @param {string} uri
*/
export function isHTTPProtocol(uri: string): boolean {
return /^(https?:)?\/\//.test(uri);
}
/**
* Apply whitespaces based on the length
* @param {*} str the log message

View file

@ -1,4 +1,3 @@
import bodyParser from 'body-parser';
import express from 'express';
/**
@ -25,9 +24,9 @@ export default class ExpressServer {
public start(port: number): Promise<ExpressServer> {
return new Promise((resolve) => {
this.app.use(bodyParser.json());
this.app.use(express.json());
this.app.use(
bodyParser.urlencoded({
express.urlencoded({
extended: true,
})
);

View file

@ -1,4 +1,3 @@
import bodyParser from 'body-parser';
import buildDebug from 'debug';
import express, { Application } from 'express';
import os from 'os';
@ -32,7 +31,7 @@ export async function initializeServer(
const auth: Auth = new Auth(config);
// FUTURE: in v6 auth.init() is being called
// TODO: this might not be need it, used in apiEndpoints
app.use(bodyParser.json({ strict: false, limit: '100mb' }));
app.use(express.json({ strict: false, limit: '100mb' }));
// @ts-ignore
app.use(errorReportingMiddleware);
for (let route of routesMiddleware) {

View file

@ -6,8 +6,6 @@ import {
addGravatarSupport,
formatAuthor,
getVersion,
getWebProtocol,
isHTTPProtocol,
normalizeDistTags,
parseReadme,
sortByName,
@ -77,39 +75,6 @@ describe('Utilities', () => {
});
});
describe('getWebProtocol', () => {
test('should handle undefined header', () => {
expect(getWebProtocol(undefined, 'http')).toBe('http');
});
test('should handle emtpy string', () => {
expect(getWebProtocol('', 'http')).toBe('http');
});
test('should have header priority over request protocol', () => {
expect(getWebProtocol('https', 'http')).toBe('https');
});
test('should have handle empty protocol', () => {
expect(getWebProtocol('https', '')).toBe('https');
});
test('should have handle invalid protocol', () => {
expect(getWebProtocol('ftp', '')).toBe('http');
});
describe('getWebProtocol and HAProxy variant', () => {
// https://github.com/verdaccio/verdaccio/issues/695
test('should handle http', () => {
expect(getWebProtocol('http,http', 'https')).toBe('http');
});
test('should handle https', () => {
expect(getWebProtocol('https,https', 'http')).toBe('https');
});
});
});
describe('normalizeDistTags', () => {
test('should delete a invalid latest version', () => {
const pkg = cloneMetadata();
@ -184,26 +149,6 @@ describe('Utilities', () => {
expect(url).toMatch('/-/static/logo.png');
});
test('should check HTTP protocol correctly', () => {
expect(isHTTPProtocol('http://domain.com/-/static/logo.png')).toBeTruthy();
expect(isHTTPProtocol('https://www.domain.com/-/static/logo.png')).toBeTruthy();
expect(isHTTPProtocol('//domain.com/-/static/logo.png')).toBeTruthy();
expect(isHTTPProtocol('file:///home/user/logo.png')).toBeFalsy();
expect(isHTTPProtocol('file:///F:/home/user/logo.png')).toBeFalsy();
// Note that uses ftp protocol in src was deprecated in modern browsers
expect(isHTTPProtocol('ftp://1.2.3.4/home/user/logo.png')).toBeFalsy();
expect(isHTTPProtocol('./logo.png')).toBeFalsy();
expect(isHTTPProtocol('.\\logo.png')).toBeFalsy();
expect(isHTTPProtocol('../logo.png')).toBeFalsy();
expect(isHTTPProtocol('..\\logo.png')).toBeFalsy();
expect(isHTTPProtocol('../../static/logo.png')).toBeFalsy();
expect(isHTTPProtocol('..\\..\\static\\logo.png')).toBeFalsy();
expect(isHTTPProtocol('logo.png')).toBeFalsy();
expect(isHTTPProtocol('.logo.png')).toBeFalsy();
expect(isHTTPProtocol('/static/logo.png')).toBeFalsy();
expect(isHTTPProtocol('F:\\static\\logo.png')).toBeFalsy();
});
test('getByQualityPriorityValue', () => {
expect(getByQualityPriorityValue('')).toEqual('');
expect(getByQualityPriorityValue(null)).toEqual('');

View file

@ -1,176 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`template custom body after 1`] = `
"
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<base href="http://domain.com">
<title></title>
<link rel="icon" href="http://domain.com-/static/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script>
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com"}
</script>
</head>
<body class="body">
<div id="root"></div>
<script defer="defer" src="http://domain.com-/static/runtime.9be80fd172e81558124c.js"></script><script defer="defer" src="http://domain.com-/static/main.9be80fd172e81558124c.js"></script>
<script src="foo"/>
</body>
</html>
"
`;
exports[`template custom body before 1`] = `
"
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<base href="http://domain.com">
<title></title>
<link rel="icon" href="http://domain.com-/static/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script>
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com"}
</script>
</head>
<body class="body">
<script src="fooBefore"/><script src="barBefore"/>
<div id="root"></div>
<script defer="defer" src="http://domain.com-/static/runtime.9be80fd172e81558124c.js"></script><script defer="defer" src="http://domain.com-/static/main.9be80fd172e81558124c.js"></script>
</body>
</html>
"
`;
exports[`template custom logo 1`] = `
"
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<base href="http://domain.com">
<title></title>
<link rel="icon" href="http://domain.com-/static/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script>
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com","logo":"http://domain/logo.png"}
</script>
</head>
<body class="body">
<div id="root"></div>
<script defer="defer" src="http://domain.com-/static/runtime.9be80fd172e81558124c.js"></script><script defer="defer" src="http://domain.com-/static/main.9be80fd172e81558124c.js"></script>
</body>
</html>
"
`;
exports[`template custom render 1`] = `
"
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<base href="http://domain.com">
<title></title>
<link rel="icon" href="http://domain.com-/static/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script>
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com"}
</script>
</head>
<body class="body">
<div id="root"></div>
<script defer="defer" src="http://domain.com-/static/runtime.9be80fd172e81558124c.js"></script><script defer="defer" src="http://domain.com-/static/main.9be80fd172e81558124c.js"></script>
</body>
</html>
"
`;
exports[`template custom title 1`] = `
"
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<base href="http://domain.com">
<title>foo title</title>
<link rel="icon" href="http://domain.com-/static/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script>
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com","title":"foo title"}
</script>
</head>
<body class="body">
<div id="root"></div>
<script defer="defer" src="http://domain.com-/static/runtime.9be80fd172e81558124c.js"></script><script defer="defer" src="http://domain.com-/static/main.9be80fd172e81558124c.js"></script>
</body>
</html>
"
`;
exports[`template custom title 2`] = `
"
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<base href="http://domain.com">
<title>foo title</title>
<link rel="icon" href="http://domain.com-/static/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script>
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com","title":"foo title"}
</script>
</head>
<body class="body">
<div id="root"></div>
<script defer="defer" src="http://domain.com-/static/runtime.9be80fd172e81558124c.js"></script><script defer="defer" src="http://domain.com-/static/main.9be80fd172e81558124c.js"></script>
</body>
</html>
"
`;
exports[`template meta scripts 1`] = `
"
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<base href="http://domain.com">
<title></title>
<link rel="icon" href="http://domain.com-/static/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script>
window.__VERDACCIO_BASENAME_UI_OPTIONS={"base":"http://domain.com"}
</script>
<style>.someclass{font-size:10px;}</style>
</head>
<body class="body">
<div id="root"></div>
<script defer="defer" src="http://domain.com-/static/runtime.9be80fd172e81558124c.js"></script><script defer="defer" src="http://domain.com-/static/main.9be80fd172e81558124c.js"></script>
</body>
</html>
"
`;

View file

@ -1,89 +0,0 @@
import renderTemplate from '../../../../src/api/web/html/template';
const manifest = require('./partials/manifest/manifest.json');
const exampleManifest = {
css: ['main.css'],
js: ['runtime.js', 'main.js'],
ico: '/static/foo.ico',
};
describe('template', () => {
test('custom render', () => {
expect(
renderTemplate(
{ options: { base: 'http://domain.com' }, manifest: exampleManifest },
manifest
)
).toMatchSnapshot();
});
test('custom title', () => {
expect(
renderTemplate(
{ options: { base: 'http://domain.com', title: 'foo title' }, manifest: exampleManifest },
manifest
)
).toMatchSnapshot();
});
test('custom title', () => {
expect(
renderTemplate(
{ options: { base: 'http://domain.com', title: 'foo title' }, manifest: exampleManifest },
manifest
)
).toMatchSnapshot();
});
test('custom logo', () => {
expect(
renderTemplate(
{
options: { base: 'http://domain.com', logo: 'http://domain/logo.png' },
manifest: exampleManifest,
},
manifest
)
).toMatchSnapshot();
});
test('meta scripts', () => {
expect(
renderTemplate(
{
options: { base: 'http://domain.com' },
metaScripts: [`<style>.someclass{font-size:10px;}</style>`],
manifest: exampleManifest,
},
manifest
)
).toMatchSnapshot();
});
test('custom body after', () => {
expect(
renderTemplate(
{
options: { base: 'http://domain.com' },
scriptsBodyAfter: [`<script src="foo"/>`],
manifest: exampleManifest,
},
manifest
)
).toMatchSnapshot();
});
test('custom body before', () => {
expect(
renderTemplate(
{
options: { base: 'http://domain.com' },
scriptsbodyBefore: [`<script src="fooBefore"/>`, `<script src="barBefore"/>`],
manifest: exampleManifest,
},
manifest
)
).toMatchSnapshot();
});
});

View file

@ -7,6 +7,7 @@
"strict": true,
"strictNullChecks": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"rootDir": "./src",
"outDir": "./build",
"allowSyntheticDefaultImports": true,

5
types/custom.d.ts vendored
View file

@ -9,3 +9,8 @@ declare global {
}
}
}
declare module '@verdaccio/types' {
export type PackageAccessYaml = any;
export type FlagsConfig = any;
}

BIN
yarn.lock

Binary file not shown.