@verdaccio/middleware 8.0.0-next-8.2 → 8.0.0-next-8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/build/index.d.ts +1 -0
  3. package/build/index.js +8 -0
  4. package/build/index.js.map +1 -1
  5. package/build/middlewares/encode-pkg.js +21 -3
  6. package/build/middlewares/encode-pkg.js.map +1 -1
  7. package/build/middlewares/log.js +2 -1
  8. package/build/middlewares/log.js.map +1 -1
  9. package/build/middlewares/make-url-relative.d.ts +8 -0
  10. package/build/middlewares/make-url-relative.js +45 -0
  11. package/build/middlewares/make-url-relative.js.map +1 -0
  12. package/build/middlewares/user-agent.js +2 -1
  13. package/build/middlewares/user-agent.js.map +1 -1
  14. package/package.json +10 -10
  15. package/src/index.ts +1 -0
  16. package/src/middlewares/encode-pkg.ts +23 -3
  17. package/src/middlewares/log.ts +3 -1
  18. package/src/middlewares/make-url-relative.ts +46 -0
  19. package/src/middlewares/user-agent.ts +2 -1
  20. package/test/__snapshots__/template.test.ts.snap +6 -6
  21. package/test/allow.spec.ts +1 -0
  22. package/test/encode.spec.ts +112 -2
  23. package/test/final.spec.ts +1 -0
  24. package/test/json.spec.ts +1 -0
  25. package/test/log.spec.ts +1 -0
  26. package/test/loop.spec.ts +1 -0
  27. package/test/make-url-relative.spec.ts +42 -0
  28. package/test/manifest.test.ts +2 -0
  29. package/test/media.spec.ts +1 -0
  30. package/test/params.spec.ts +1 -0
  31. package/test/render.spec.ts +1 -0
  32. package/test/security.spec.ts +1 -0
  33. package/test/static/runtime.js +3 -0
  34. package/test/static/vendors.js +3 -0
  35. package/test/template.test.ts +2 -0
  36. package/test/utils.spec.ts +2 -0
  37. package/test/validation.spec.ts +1 -0
  38. package/jest.config.js +0 -12
  39. package/test/static/vendor.js +0 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # @verdaccio/middleware
2
2
 
3
+ ## 8.0.0-next-8.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 48aa89f: chore: request header constants
8
+ - 58e0d95: fix(middleware): error 404 when getting scoped tarballs
9
+ - 1076a89: chore(middleware): fix syntax of test files
10
+ - e93d6a3: chore: auth package requires logger as parameter
11
+ - Updated dependencies [48aa89f]
12
+ - Updated dependencies [58e0d95]
13
+ - @verdaccio/core@8.0.0-next-8.4
14
+ - @verdaccio/config@8.0.0-next-8.4
15
+ - @verdaccio/url@13.0.0-next-8.4
16
+ - @verdaccio/utils@8.1.0-next-8.4
17
+
18
+ ## 8.0.0-next-8.3
19
+
20
+ ### Patch Changes
21
+
22
+ - 5bb81eb: fix(middleware): encoding of scope package name
23
+ - @verdaccio/core@8.0.0-next-8.3
24
+ - @verdaccio/config@8.0.0-next-8.3
25
+ - @verdaccio/url@13.0.0-next-8.3
26
+ - @verdaccio/utils@8.1.0-next-8.3
27
+
3
28
  ## 8.0.0-next-8.2
4
29
 
5
30
  ### Minor Changes
package/build/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export { match } from './middlewares/match';
2
2
  export { setSecurityWebHeaders } from './middlewares/security-headers';
3
3
  export { validateName, validatePackage } from './middlewares/validation';
4
4
  export { media } from './middlewares/media';
5
+ export { makeURLrelative } from './middlewares/make-url-relative';
5
6
  export { encodeScopePackage } from './middlewares/encode-pkg';
6
7
  export { expectJson } from './middlewares/json';
7
8
  export { antiLoop } from './middlewares/antiLoop';
package/build/index.js CHANGED
@@ -9,6 +9,7 @@ var _exportNames = {
9
9
  validateName: true,
10
10
  validatePackage: true,
11
11
  media: true,
12
+ makeURLrelative: true,
12
13
  encodeScopePackage: true,
13
14
  expectJson: true,
14
15
  antiLoop: true,
@@ -91,6 +92,12 @@ Object.defineProperty(exports, "log", {
91
92
  return _log.log;
92
93
  }
93
94
  });
95
+ Object.defineProperty(exports, "makeURLrelative", {
96
+ enumerable: true,
97
+ get: function () {
98
+ return _makeUrlRelative.makeURLrelative;
99
+ }
100
+ });
94
101
  Object.defineProperty(exports, "match", {
95
102
  enumerable: true,
96
103
  get: function () {
@@ -149,6 +156,7 @@ var _match = require("./middlewares/match");
149
156
  var _securityHeaders = require("./middlewares/security-headers");
150
157
  var _validation = require("./middlewares/validation");
151
158
  var _media = require("./middlewares/media");
159
+ var _makeUrlRelative = require("./middlewares/make-url-relative");
152
160
  var _encodePkg = require("./middlewares/encode-pkg");
153
161
  var _json = require("./middlewares/json");
154
162
  var _antiLoop = require("./middlewares/antiLoop");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_match","require","_securityHeaders","_validation","_media","_encodePkg","_json","_antiLoop","_final","_allow","_rateLimit","_userAgent","_web","_error","_log","_types","Object","keys","forEach","key","prototype","hasOwnProperty","call","_exportNames","exports","defineProperty","enumerable","get"],"sources":["../src/index.ts"],"sourcesContent":["export { match } from './middlewares/match';\nexport { setSecurityWebHeaders } from './middlewares/security-headers';\nexport { validateName, validatePackage } from './middlewares/validation';\nexport { media } from './middlewares/media';\nexport { encodeScopePackage } from './middlewares/encode-pkg';\nexport { expectJson } from './middlewares/json';\nexport { antiLoop } from './middlewares/antiLoop';\nexport { final } from './middlewares/final';\nexport { allow } from './middlewares/allow';\nexport { rateLimit } from './middlewares/rate-limit';\nexport { userAgent } from './middlewares/user-agent';\nexport { webMiddleware, renderWebMiddleware } from './middlewares/web';\nexport { errorReportingMiddleware, handleError } from './middlewares/error';\nexport {\n log,\n LOG_STATUS_MESSAGE,\n LOG_VERDACCIO_BYTES,\n LOG_VERDACCIO_ERROR,\n} from './middlewares/log';\nexport * from './types';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,gBAAA,GAAAD,OAAA;AACA,IAAAE,WAAA,GAAAF,OAAA;AACA,IAAAG,MAAA,GAAAH,OAAA;AACA,IAAAI,UAAA,GAAAJ,OAAA;AACA,IAAAK,KAAA,GAAAL,OAAA;AACA,IAAAM,SAAA,GAAAN,OAAA;AACA,IAAAO,MAAA,GAAAP,OAAA;AACA,IAAAQ,MAAA,GAAAR,OAAA;AACA,IAAAS,UAAA,GAAAT,OAAA;AACA,IAAAU,UAAA,GAAAV,OAAA;AACA,IAAAW,IAAA,GAAAX,OAAA;AACA,IAAAY,MAAA,GAAAZ,OAAA;AACA,IAAAa,IAAA,GAAAb,OAAA;AAMA,IAAAc,MAAA,GAAAd,OAAA;AAAAe,MAAA,CAAAC,IAAA,CAAAF,MAAA,EAAAG,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAH,MAAA,CAAAI,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAC,YAAA,EAAAJ,GAAA;EAAA,IAAAA,GAAA,IAAAK,OAAA,IAAAA,OAAA,CAAAL,GAAA,MAAAJ,MAAA,CAAAI,GAAA;EAAAH,MAAA,CAAAS,cAAA,CAAAD,OAAA,EAAAL,GAAA;IAAAO,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAZ,MAAA,CAAAI,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["_match","require","_securityHeaders","_validation","_media","_makeUrlRelative","_encodePkg","_json","_antiLoop","_final","_allow","_rateLimit","_userAgent","_web","_error","_log","_types","Object","keys","forEach","key","prototype","hasOwnProperty","call","_exportNames","exports","defineProperty","enumerable","get"],"sources":["../src/index.ts"],"sourcesContent":["export { match } from './middlewares/match';\nexport { setSecurityWebHeaders } from './middlewares/security-headers';\nexport { validateName, validatePackage } from './middlewares/validation';\nexport { media } from './middlewares/media';\nexport { makeURLrelative } from './middlewares/make-url-relative';\nexport { encodeScopePackage } from './middlewares/encode-pkg';\nexport { expectJson } from './middlewares/json';\nexport { antiLoop } from './middlewares/antiLoop';\nexport { final } from './middlewares/final';\nexport { allow } from './middlewares/allow';\nexport { rateLimit } from './middlewares/rate-limit';\nexport { userAgent } from './middlewares/user-agent';\nexport { webMiddleware, renderWebMiddleware } from './middlewares/web';\nexport { errorReportingMiddleware, handleError } from './middlewares/error';\nexport {\n log,\n LOG_STATUS_MESSAGE,\n LOG_VERDACCIO_BYTES,\n LOG_VERDACCIO_ERROR,\n} from './middlewares/log';\nexport * from './types';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,gBAAA,GAAAD,OAAA;AACA,IAAAE,WAAA,GAAAF,OAAA;AACA,IAAAG,MAAA,GAAAH,OAAA;AACA,IAAAI,gBAAA,GAAAJ,OAAA;AACA,IAAAK,UAAA,GAAAL,OAAA;AACA,IAAAM,KAAA,GAAAN,OAAA;AACA,IAAAO,SAAA,GAAAP,OAAA;AACA,IAAAQ,MAAA,GAAAR,OAAA;AACA,IAAAS,MAAA,GAAAT,OAAA;AACA,IAAAU,UAAA,GAAAV,OAAA;AACA,IAAAW,UAAA,GAAAX,OAAA;AACA,IAAAY,IAAA,GAAAZ,OAAA;AACA,IAAAa,MAAA,GAAAb,OAAA;AACA,IAAAc,IAAA,GAAAd,OAAA;AAMA,IAAAe,MAAA,GAAAf,OAAA;AAAAgB,MAAA,CAAAC,IAAA,CAAAF,MAAA,EAAAG,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAH,MAAA,CAAAI,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAC,YAAA,EAAAJ,GAAA;EAAA,IAAAA,GAAA,IAAAK,OAAA,IAAAA,OAAA,CAAAL,GAAA,MAAAJ,MAAA,CAAAI,GAAA;EAAAH,MAAA,CAAAS,cAAA,CAAAD,OAAA,EAAAL,GAAA;IAAAO,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAZ,MAAA,CAAAI,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
@@ -4,6 +4,11 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.encodeScopePackage = encodeScopePackage;
7
+ var _debug = _interopRequireDefault(require("debug"));
8
+ var _core = require("@verdaccio/core");
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
+ const debug = (0, _debug.default)('verdaccio:middleware:encode');
11
+
7
12
  /**
8
13
  * Encode / in a scoped package name to be matched as a single parameter in routes
9
14
  * @param req
@@ -11,9 +16,22 @@ exports.encodeScopePackage = encodeScopePackage;
11
16
  * @param next
12
17
  */
13
18
  function encodeScopePackage(req, res, next) {
14
- if (req.url.indexOf('@') !== -1) {
15
- // e.g.: /@org/pkg/1.2.3 -> /@org%2Fpkg/1.2.3, /@org%2Fpkg/1.2.3 -> /@org%2Fpkg/1.2.3
16
- req.url = req.url.replace(/^(\/@[^\/%]+)\/(?!$)/, '$1%2F');
19
+ const original = req.url;
20
+
21
+ // Expect relative URLs i.e. should call makeURLrelative before this middleware
22
+ if (!req.url.startsWith('/')) {
23
+ return next(_core.errorUtils.getBadRequest(`Invalid URL: ${req.url} (must be relative)`));
24
+ }
25
+
26
+ // If the @ sign is encoded, we need to decode it first
27
+ // e.g.: /%40org/pkg/1.2.3 -> /@org/pkg/1.2.3
28
+ // For scoped packages, encode the slash to make it a single path segment/parameter
29
+ // e.g.: /@org/pkg/1.2.3 -> /@org%2Fpkg/1.2.3, /@org%2Fpkg/1.2.3 -> /@org%2Fpkg/1.2.3
30
+ req.url = req.url.replace(/^\/%40/, '/@').replace(/^(\/@[^\/%]+)\/(?!$)/, '$1%2F');
31
+ if (original !== req.url) {
32
+ debug('encodeScopePackage: %o -> %o', original, req.url);
33
+ } else {
34
+ debug('encodeScopePackage: %o (unchanged)', original);
17
35
  }
18
36
  next();
19
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"encode-pkg.js","names":["encodeScopePackage","req","res","next","url","indexOf","replace"],"sources":["../../src/middlewares/encode-pkg.ts"],"sourcesContent":["import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';\n\n/**\n * Encode / in a scoped package name to be matched as a single parameter in routes\n * @param req\n * @param res\n * @param next\n */\nexport function encodeScopePackage(\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n): void {\n if (req.url.indexOf('@') !== -1) {\n // e.g.: /@org/pkg/1.2.3 -> /@org%2Fpkg/1.2.3, /@org%2Fpkg/1.2.3 -> /@org%2Fpkg/1.2.3\n req.url = req.url.replace(/^(\\/@[^\\/%]+)\\/(?!$)/, '$1%2F');\n }\n next();\n}\n"],"mappings":";;;;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAASA,kBAAkBA,CAChCC,GAAmB,EACnBC,GAAoB,EACpBC,IAAsB,EAChB;EACN,IAAIF,GAAG,CAACG,GAAG,CAACC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE;IAC/B;IACAJ,GAAG,CAACG,GAAG,GAAGH,GAAG,CAACG,GAAG,CAACE,OAAO,CAAC,sBAAsB,EAAE,OAAO,CAAC;EAC5D;EACAH,IAAI,CAAC,CAAC;AACR","ignoreList":[]}
1
+ {"version":3,"file":"encode-pkg.js","names":["_debug","_interopRequireDefault","require","_core","e","__esModule","default","debug","buildDebug","encodeScopePackage","req","res","next","original","url","startsWith","errorUtils","getBadRequest","replace"],"sources":["../../src/middlewares/encode-pkg.ts"],"sourcesContent":["import buildDebug from 'debug';\n\nimport { errorUtils } from '@verdaccio/core';\n\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';\n\nconst debug = buildDebug('verdaccio:middleware:encode');\n\n/**\n * Encode / in a scoped package name to be matched as a single parameter in routes\n * @param req\n * @param res\n * @param next\n */\nexport function encodeScopePackage(\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n): void {\n const original = req.url;\n\n // Expect relative URLs i.e. should call makeURLrelative before this middleware\n if (!req.url.startsWith('/')) {\n return next(errorUtils.getBadRequest(`Invalid URL: ${req.url} (must be relative)`));\n }\n\n // If the @ sign is encoded, we need to decode it first\n // e.g.: /%40org/pkg/1.2.3 -> /@org/pkg/1.2.3\n // For scoped packages, encode the slash to make it a single path segment/parameter\n // e.g.: /@org/pkg/1.2.3 -> /@org%2Fpkg/1.2.3, /@org%2Fpkg/1.2.3 -> /@org%2Fpkg/1.2.3\n req.url = req.url.replace(/^\\/%40/, '/@').replace(/^(\\/@[^\\/%]+)\\/(?!$)/, '$1%2F');\n\n if (original !== req.url) {\n debug('encodeScopePackage: %o -> %o', original, req.url);\n } else {\n debug('encodeScopePackage: %o (unchanged)', original);\n }\n next();\n}\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AAEA,IAAAC,KAAA,GAAAD,OAAA;AAA6C,SAAAD,uBAAAG,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAI7C,MAAMG,KAAK,GAAG,IAAAC,cAAU,EAAC,6BAA6B,CAAC;;AAEvD;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,kBAAkBA,CAChCC,GAAmB,EACnBC,GAAoB,EACpBC,IAAsB,EAChB;EACN,MAAMC,QAAQ,GAAGH,GAAG,CAACI,GAAG;;EAExB;EACA,IAAI,CAACJ,GAAG,CAACI,GAAG,CAACC,UAAU,CAAC,GAAG,CAAC,EAAE;IAC5B,OAAOH,IAAI,CAACI,gBAAU,CAACC,aAAa,CAAC,gBAAgBP,GAAG,CAACI,GAAG,qBAAqB,CAAC,CAAC;EACrF;;EAEA;EACA;EACA;EACA;EACAJ,GAAG,CAACI,GAAG,GAAGJ,GAAG,CAACI,GAAG,CAACI,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAACA,OAAO,CAAC,sBAAsB,EAAE,OAAO,CAAC;EAElF,IAAIL,QAAQ,KAAKH,GAAG,CAACI,GAAG,EAAE;IACxBP,KAAK,CAAC,8BAA8B,EAAEM,QAAQ,EAAEH,GAAG,CAACI,GAAG,CAAC;EAC1D,CAAC,MAAM;IACLP,KAAK,CAAC,oCAAoC,EAAEM,QAAQ,CAAC;EACvD;EACAD,IAAI,CAAC,CAAC;AACR","ignoreList":[]}
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.log = exports.LOG_VERDACCIO_ERROR = exports.LOG_VERDACCIO_BYTES = exports.LOG_STATUS_MESSAGE = void 0;
7
7
  var _lodash = _interopRequireDefault(require("lodash"));
8
+ var _core = require("@verdaccio/core");
8
9
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
10
  // FIXME: deprecated, moved to @verdaccio/dev-commons
10
11
  const LOG_STATUS_MESSAGE = exports.LOG_STATUS_MESSAGE = "@{status}, user: @{user}(@{remoteIP}), req: '@{request.method} @{request.url}'";
@@ -51,7 +52,7 @@ const log = logger => {
51
52
  _write.apply(res, arguments);
52
53
  };
53
54
  const log = function () {
54
- const forwardedFor = req.get('x-forwarded-for');
55
+ const forwardedFor = req.get(_core.HEADERS.FORWARDED_FOR);
55
56
  const remoteAddress = req.connection.remoteAddress;
56
57
  const remoteIP = forwardedFor ? `${forwardedFor} via ${remoteAddress}` : remoteAddress;
57
58
  let message;
@@ -1 +1 @@
1
- {"version":3,"file":"log.js","names":["_lodash","_interopRequireDefault","require","e","__esModule","default","LOG_STATUS_MESSAGE","exports","LOG_VERDACCIO_ERROR","LOG_VERDACCIO_BYTES","log","logger","req","res","next","child","sub","_auth","headers","authorization","_","isNil","_cookie","get","cookie","url","originalUrl","info","ip","bytesin","on","chunk","length","bytesout","_write","write","buf","apply","arguments","forwardedFor","remoteAddress","connection","remoteIP","message","locals","_verdaccio_error","http","request","method","user","remote_user","name","status","statusCode","error","bytes","in","out","_end","end"],"sources":["../../src/middlewares/log.ts"],"sourcesContent":["import _ from 'lodash';\n\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';\n\n// FIXME: deprecated, moved to @verdaccio/dev-commons\nexport const LOG_STATUS_MESSAGE =\n \"@{status}, user: @{user}(@{remoteIP}), req: '@{request.method} @{request.url}'\";\nexport const LOG_VERDACCIO_ERROR = `${LOG_STATUS_MESSAGE}, error: @{!error}`;\nexport const LOG_VERDACCIO_BYTES = `${LOG_STATUS_MESSAGE}, bytes: @{bytes.in}/@{bytes.out}`;\n\nexport const log = (logger) => {\n return function log(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {\n // logger\n req.log = logger.child({ sub: 'in' });\n\n const _auth = req.headers.authorization;\n if (_.isNil(_auth) === false) {\n req.headers.authorization = '<Classified>';\n }\n\n const _cookie = req.get('cookie');\n if (_.isNil(_cookie) === false) {\n req.headers.cookie = '<Classified>';\n }\n\n req.url = req.originalUrl;\n req.log.info({ req: req, ip: req.ip }, \"@{ip} requested '@{req.method} @{req.url}'\");\n req.originalUrl = req.url;\n\n if (_.isNil(_auth) === false) {\n req.headers.authorization = _auth;\n }\n\n if (_.isNil(_cookie) === false) {\n req.headers.cookie = _cookie;\n }\n\n let bytesin = 0;\n req.on('data', function (chunk): void {\n bytesin += chunk.length;\n });\n\n let bytesout = 0;\n const _write = res.write;\n // FIXME: res.write should return boolean\n // @ts-ignore\n res.write = function (buf): boolean {\n bytesout += buf.length;\n /* eslint prefer-rest-params: \"off\" */\n // @ts-ignore\n _write.apply(res, arguments);\n };\n\n const log = function (): void {\n const forwardedFor = req.get('x-forwarded-for');\n const remoteAddress = req.connection.remoteAddress;\n const remoteIP = forwardedFor ? `${forwardedFor} via ${remoteAddress}` : remoteAddress;\n let message;\n if (res.locals._verdaccio_error) {\n message = LOG_VERDACCIO_ERROR;\n } else {\n message = LOG_VERDACCIO_BYTES;\n }\n\n req.url = req.originalUrl;\n req.log.http(\n {\n request: {\n method: req.method,\n url: req.url,\n },\n user: req.remote_user?.name || null,\n remoteIP,\n status: res.statusCode,\n error: res.locals._verdaccio_error,\n bytes: {\n in: bytesin,\n out: bytesout,\n },\n },\n message\n );\n req.originalUrl = req.url;\n };\n\n req.on('close', function (): void {\n log();\n });\n\n const _end = res.end;\n // @ts-ignore\n res.end = function (buf): void {\n if (buf) {\n bytesout += buf.length;\n }\n /* eslint prefer-rest-params: \"off\" */\n // @ts-ignore\n _end.apply(res, arguments);\n log();\n };\n next();\n };\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"log.js","names":["_lodash","_interopRequireDefault","require","_core","e","__esModule","default","LOG_STATUS_MESSAGE","exports","LOG_VERDACCIO_ERROR","LOG_VERDACCIO_BYTES","log","logger","req","res","next","child","sub","_auth","headers","authorization","_","isNil","_cookie","get","cookie","url","originalUrl","info","ip","bytesin","on","chunk","length","bytesout","_write","write","buf","apply","arguments","forwardedFor","HEADERS","FORWARDED_FOR","remoteAddress","connection","remoteIP","message","locals","_verdaccio_error","http","request","method","user","remote_user","name","status","statusCode","error","bytes","in","out","_end","end"],"sources":["../../src/middlewares/log.ts"],"sourcesContent":["import _ from 'lodash';\n\nimport { HEADERS } from '@verdaccio/core';\n\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';\n\n// FIXME: deprecated, moved to @verdaccio/dev-commons\nexport const LOG_STATUS_MESSAGE =\n \"@{status}, user: @{user}(@{remoteIP}), req: '@{request.method} @{request.url}'\";\nexport const LOG_VERDACCIO_ERROR = `${LOG_STATUS_MESSAGE}, error: @{!error}`;\nexport const LOG_VERDACCIO_BYTES = `${LOG_STATUS_MESSAGE}, bytes: @{bytes.in}/@{bytes.out}`;\n\nexport const log = (logger) => {\n return function log(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {\n // logger\n req.log = logger.child({ sub: 'in' });\n\n const _auth = req.headers.authorization;\n if (_.isNil(_auth) === false) {\n req.headers.authorization = '<Classified>';\n }\n\n const _cookie = req.get('cookie');\n if (_.isNil(_cookie) === false) {\n req.headers.cookie = '<Classified>';\n }\n\n req.url = req.originalUrl;\n req.log.info({ req: req, ip: req.ip }, \"@{ip} requested '@{req.method} @{req.url}'\");\n req.originalUrl = req.url;\n\n if (_.isNil(_auth) === false) {\n req.headers.authorization = _auth;\n }\n\n if (_.isNil(_cookie) === false) {\n req.headers.cookie = _cookie;\n }\n\n let bytesin = 0;\n req.on('data', function (chunk): void {\n bytesin += chunk.length;\n });\n\n let bytesout = 0;\n const _write = res.write;\n // FIXME: res.write should return boolean\n // @ts-ignore\n res.write = function (buf): boolean {\n bytesout += buf.length;\n /* eslint prefer-rest-params: \"off\" */\n // @ts-ignore\n _write.apply(res, arguments);\n };\n\n const log = function (): void {\n const forwardedFor = req.get(HEADERS.FORWARDED_FOR);\n const remoteAddress = req.connection.remoteAddress;\n const remoteIP = forwardedFor ? `${forwardedFor} via ${remoteAddress}` : remoteAddress;\n let message;\n if (res.locals._verdaccio_error) {\n message = LOG_VERDACCIO_ERROR;\n } else {\n message = LOG_VERDACCIO_BYTES;\n }\n\n req.url = req.originalUrl;\n req.log.http(\n {\n request: {\n method: req.method,\n url: req.url,\n },\n user: req.remote_user?.name || null,\n remoteIP,\n status: res.statusCode,\n error: res.locals._verdaccio_error,\n bytes: {\n in: bytesin,\n out: bytesout,\n },\n },\n message\n );\n req.originalUrl = req.url;\n };\n\n req.on('close', function (): void {\n log();\n });\n\n const _end = res.end;\n // @ts-ignore\n res.end = function (buf): void {\n if (buf) {\n bytesout += buf.length;\n }\n /* eslint prefer-rest-params: \"off\" */\n // @ts-ignore\n _end.apply(res, arguments);\n log();\n };\n next();\n };\n};\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,8 @@
1
+ import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';
2
+ /**
3
+ * Removes the host from the URL and turns it into a relative URL.
4
+ * @param req
5
+ * @param res
6
+ * @param next
7
+ */
8
+ export declare function makeURLrelative(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.makeURLrelative = makeURLrelative;
7
+ var _debug = _interopRequireDefault(require("debug"));
8
+ var _nodeUrl = require("node:url");
9
+ var _core = require("@verdaccio/core");
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ const debug = (0, _debug.default)('verdaccio:middleware:make-url-relative');
12
+
13
+ /**
14
+ * Removes the host from the URL and turns it into a relative URL.
15
+ * @param req
16
+ * @param res
17
+ * @param next
18
+ */
19
+ function makeURLrelative(req, res, next) {
20
+ const original = req.url;
21
+
22
+ // npm requests can contain the full URL, including the hostname, for example:
23
+ // tarball downloads. Removing the hostname makes the URL relative and allows
24
+ // the application to handle requests in a more consistent way.
25
+
26
+ let url;
27
+ try {
28
+ // In productive use, the URL is absolute (and base will be ignored)
29
+ // In tests, the URL might brelative (and base will be used)
30
+ // https://nodejs.org/docs/latest/api/url.html#new-urlinput-base
31
+ url = new _nodeUrl.URL(req.url, `${req.protocol}://${req.headers.host}/`);
32
+ } catch (error) {
33
+ return next(_core.errorUtils.getBadRequest(`Invalid URL: ${req.url} (${error})`));
34
+ }
35
+
36
+ // Rebuild the URL without hostname
37
+ req.url = url.pathname + url.search + url.hash;
38
+ if (original !== req.url) {
39
+ debug('makeURLrelative: %o -> %o', original, req.url);
40
+ } else {
41
+ debug('makeURLrelative: %o (unchanged)', original);
42
+ }
43
+ next();
44
+ }
45
+ //# sourceMappingURL=make-url-relative.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"make-url-relative.js","names":["_debug","_interopRequireDefault","require","_nodeUrl","_core","e","__esModule","default","debug","buildDebug","makeURLrelative","req","res","next","original","url","URL","protocol","headers","host","error","errorUtils","getBadRequest","pathname","search","hash"],"sources":["../../src/middlewares/make-url-relative.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { URL } from 'node:url';\n\nimport { errorUtils } from '@verdaccio/core';\n\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';\n\nconst debug = buildDebug('verdaccio:middleware:make-url-relative');\n\n/**\n * Removes the host from the URL and turns it into a relative URL.\n * @param req\n * @param res\n * @param next\n */\nexport function makeURLrelative(\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n): void {\n const original = req.url;\n\n // npm requests can contain the full URL, including the hostname, for example:\n // tarball downloads. Removing the hostname makes the URL relative and allows\n // the application to handle requests in a more consistent way.\n\n let url;\n try {\n // In productive use, the URL is absolute (and base will be ignored)\n // In tests, the URL might brelative (and base will be used)\n // https://nodejs.org/docs/latest/api/url.html#new-urlinput-base\n url = new URL(req.url, `${req.protocol}://${req.headers.host}/`);\n } catch (error) {\n return next(errorUtils.getBadRequest(`Invalid URL: ${req.url} (${error})`));\n }\n\n // Rebuild the URL without hostname\n req.url = url.pathname + url.search + url.hash;\n\n if (original !== req.url) {\n debug('makeURLrelative: %o -> %o', original, req.url);\n } else {\n debug('makeURLrelative: %o (unchanged)', original);\n }\n next();\n}\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,QAAA,GAAAD,OAAA;AAEA,IAAAE,KAAA,GAAAF,OAAA;AAA6C,SAAAD,uBAAAI,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAI7C,MAAMG,KAAK,GAAG,IAAAC,cAAU,EAAC,wCAAwC,CAAC;;AAElE;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,eAAeA,CAC7BC,GAAmB,EACnBC,GAAoB,EACpBC,IAAsB,EAChB;EACN,MAAMC,QAAQ,GAAGH,GAAG,CAACI,GAAG;;EAExB;EACA;EACA;;EAEA,IAAIA,GAAG;EACP,IAAI;IACF;IACA;IACA;IACAA,GAAG,GAAG,IAAIC,YAAG,CAACL,GAAG,CAACI,GAAG,EAAE,GAAGJ,GAAG,CAACM,QAAQ,MAAMN,GAAG,CAACO,OAAO,CAACC,IAAI,GAAG,CAAC;EAClE,CAAC,CAAC,OAAOC,KAAK,EAAE;IACd,OAAOP,IAAI,CAACQ,gBAAU,CAACC,aAAa,CAAC,gBAAgBX,GAAG,CAACI,GAAG,KAAKK,KAAK,GAAG,CAAC,CAAC;EAC7E;;EAEA;EACAT,GAAG,CAACI,GAAG,GAAGA,GAAG,CAACQ,QAAQ,GAAGR,GAAG,CAACS,MAAM,GAAGT,GAAG,CAACU,IAAI;EAE9C,IAAIX,QAAQ,KAAKH,GAAG,CAACI,GAAG,EAAE;IACxBP,KAAK,CAAC,2BAA2B,EAAEM,QAAQ,EAAEH,GAAG,CAACI,GAAG,CAAC;EACvD,CAAC,MAAM;IACLP,KAAK,CAAC,iCAAiC,EAAEM,QAAQ,CAAC;EACpD;EACAD,IAAI,CAAC,CAAC;AACR","ignoreList":[]}
@@ -5,9 +5,10 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.userAgent = userAgent;
7
7
  var _config = require("@verdaccio/config");
8
+ var _core = require("@verdaccio/core");
8
9
  function userAgent(config) {
9
10
  return function (_req, res, next) {
10
- res.setHeader('x-powered-by', (0, _config.getUserAgent)(config?.user_agent));
11
+ res.setHeader(_core.HEADERS.POWERED_BY, (0, _config.getUserAgent)(config?.user_agent));
11
12
  next();
12
13
  };
13
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"user-agent.js","names":["_config","require","userAgent","config","_req","res","next","setHeader","getUserAgent","user_agent"],"sources":["../../src/middlewares/user-agent.ts"],"sourcesContent":["import { getUserAgent } from '@verdaccio/config';\n\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';\n\nexport function userAgent(config) {\n return function (_req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {\n res.setHeader('x-powered-by', getUserAgent(config?.user_agent));\n next();\n };\n}\n"],"mappings":";;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AAIO,SAASC,SAASA,CAACC,MAAM,EAAE;EAChC,OAAO,UAAUC,IAAoB,EAAEC,GAAoB,EAAEC,IAAsB,EAAQ;IACzFD,GAAG,CAACE,SAAS,CAAC,cAAc,EAAE,IAAAC,oBAAY,EAACL,MAAM,EAAEM,UAAU,CAAC,CAAC;IAC/DH,IAAI,CAAC,CAAC;EACR,CAAC;AACH","ignoreList":[]}
1
+ {"version":3,"file":"user-agent.js","names":["_config","require","_core","userAgent","config","_req","res","next","setHeader","HEADERS","POWERED_BY","getUserAgent","user_agent"],"sources":["../../src/middlewares/user-agent.ts"],"sourcesContent":["import { getUserAgent } from '@verdaccio/config';\nimport { HEADERS } from '@verdaccio/core';\n\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';\n\nexport function userAgent(config) {\n return function (_req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {\n res.setHeader(HEADERS.POWERED_BY, getUserAgent(config?.user_agent));\n next();\n };\n}\n"],"mappings":";;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,KAAA,GAAAD,OAAA;AAIO,SAASE,SAASA,CAACC,MAAM,EAAE;EAChC,OAAO,UAAUC,IAAoB,EAAEC,GAAoB,EAAEC,IAAsB,EAAQ;IACzFD,GAAG,CAACE,SAAS,CAACC,aAAO,CAACC,UAAU,EAAE,IAAAC,oBAAY,EAACP,MAAM,EAAEQ,UAAU,CAAC,CAAC;IACnEL,IAAI,CAAC,CAAC;EACR,CAAC;AACH","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdaccio/middleware",
3
- "version": "8.0.0-next-8.2",
3
+ "version": "8.0.0-next-8.4",
4
4
  "description": "express middleware utils",
5
5
  "main": "./build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -29,12 +29,12 @@
29
29
  "node": ">=18"
30
30
  },
31
31
  "dependencies": {
32
- "@verdaccio/config": "8.0.0-next-8.2",
33
- "@verdaccio/core": "8.0.0-next-8.2",
34
- "@verdaccio/url": "13.0.0-next-8.2",
35
- "@verdaccio/utils": "7.1.0-next-8.2",
32
+ "@verdaccio/config": "8.0.0-next-8.4",
33
+ "@verdaccio/core": "8.0.0-next-8.4",
34
+ "@verdaccio/url": "13.0.0-next-8.4",
35
+ "@verdaccio/utils": "8.1.0-next-8.4",
36
36
  "debug": "4.3.7",
37
- "express": "4.21.0",
37
+ "express": "4.21.1",
38
38
  "express-rate-limit": "5.5.1",
39
39
  "lodash": "4.17.21",
40
40
  "lru-cache": "7.18.3",
@@ -45,9 +45,10 @@
45
45
  "url": "https://opencollective.com/verdaccio"
46
46
  },
47
47
  "devDependencies": {
48
- "@verdaccio/logger": "8.0.0-next-8.2",
48
+ "@verdaccio/logger": "8.0.0-next-8.4",
49
49
  "body-parser": "1.20.3",
50
- "supertest": "7.0.0"
50
+ "supertest": "7.0.0",
51
+ "jsdom": "25.0.1"
51
52
  },
52
53
  "scripts": {
53
54
  "clean": "rimraf ./build",
@@ -55,8 +56,7 @@
55
56
  "build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
56
57
  "build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
57
58
  "watch": "pnpm build:js -- --watch",
58
- "test": "jest",
59
- "test:snap": "jest --updateSnapshot",
59
+ "test": "vitest run",
60
60
  "build": "pnpm run build:js && pnpm run build:types"
61
61
  }
62
62
  }
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@ export { match } from './middlewares/match';
2
2
  export { setSecurityWebHeaders } from './middlewares/security-headers';
3
3
  export { validateName, validatePackage } from './middlewares/validation';
4
4
  export { media } from './middlewares/media';
5
+ export { makeURLrelative } from './middlewares/make-url-relative';
5
6
  export { encodeScopePackage } from './middlewares/encode-pkg';
6
7
  export { expectJson } from './middlewares/json';
7
8
  export { antiLoop } from './middlewares/antiLoop';
@@ -1,5 +1,11 @@
1
+ import buildDebug from 'debug';
2
+
3
+ import { errorUtils } from '@verdaccio/core';
4
+
1
5
  import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';
2
6
 
7
+ const debug = buildDebug('verdaccio:middleware:encode');
8
+
3
9
  /**
4
10
  * Encode / in a scoped package name to be matched as a single parameter in routes
5
11
  * @param req
@@ -11,9 +17,23 @@ export function encodeScopePackage(
11
17
  res: $ResponseExtend,
12
18
  next: $NextFunctionVer
13
19
  ): void {
14
- if (req.url.indexOf('@') !== -1) {
15
- // e.g.: /@org/pkg/1.2.3 -> /@org%2Fpkg/1.2.3, /@org%2Fpkg/1.2.3 -> /@org%2Fpkg/1.2.3
16
- req.url = req.url.replace(/^(\/@[^\/%]+)\/(?!$)/, '$1%2F');
20
+ const original = req.url;
21
+
22
+ // Expect relative URLs i.e. should call makeURLrelative before this middleware
23
+ if (!req.url.startsWith('/')) {
24
+ return next(errorUtils.getBadRequest(`Invalid URL: ${req.url} (must be relative)`));
25
+ }
26
+
27
+ // If the @ sign is encoded, we need to decode it first
28
+ // e.g.: /%40org/pkg/1.2.3 -> /@org/pkg/1.2.3
29
+ // For scoped packages, encode the slash to make it a single path segment/parameter
30
+ // e.g.: /@org/pkg/1.2.3 -> /@org%2Fpkg/1.2.3, /@org%2Fpkg/1.2.3 -> /@org%2Fpkg/1.2.3
31
+ req.url = req.url.replace(/^\/%40/, '/@').replace(/^(\/@[^\/%]+)\/(?!$)/, '$1%2F');
32
+
33
+ if (original !== req.url) {
34
+ debug('encodeScopePackage: %o -> %o', original, req.url);
35
+ } else {
36
+ debug('encodeScopePackage: %o (unchanged)', original);
17
37
  }
18
38
  next();
19
39
  }
@@ -1,5 +1,7 @@
1
1
  import _ from 'lodash';
2
2
 
3
+ import { HEADERS } from '@verdaccio/core';
4
+
3
5
  import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';
4
6
 
5
7
  // FIXME: deprecated, moved to @verdaccio/dev-commons
@@ -52,7 +54,7 @@ export const log = (logger) => {
52
54
  };
53
55
 
54
56
  const log = function (): void {
55
- const forwardedFor = req.get('x-forwarded-for');
57
+ const forwardedFor = req.get(HEADERS.FORWARDED_FOR);
56
58
  const remoteAddress = req.connection.remoteAddress;
57
59
  const remoteIP = forwardedFor ? `${forwardedFor} via ${remoteAddress}` : remoteAddress;
58
60
  let message;
@@ -0,0 +1,46 @@
1
+ import buildDebug from 'debug';
2
+ import { URL } from 'node:url';
3
+
4
+ import { errorUtils } from '@verdaccio/core';
5
+
6
+ import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';
7
+
8
+ const debug = buildDebug('verdaccio:middleware:make-url-relative');
9
+
10
+ /**
11
+ * Removes the host from the URL and turns it into a relative URL.
12
+ * @param req
13
+ * @param res
14
+ * @param next
15
+ */
16
+ export function makeURLrelative(
17
+ req: $RequestExtend,
18
+ res: $ResponseExtend,
19
+ next: $NextFunctionVer
20
+ ): void {
21
+ const original = req.url;
22
+
23
+ // npm requests can contain the full URL, including the hostname, for example:
24
+ // tarball downloads. Removing the hostname makes the URL relative and allows
25
+ // the application to handle requests in a more consistent way.
26
+
27
+ let url;
28
+ try {
29
+ // In productive use, the URL is absolute (and base will be ignored)
30
+ // In tests, the URL might brelative (and base will be used)
31
+ // https://nodejs.org/docs/latest/api/url.html#new-urlinput-base
32
+ url = new URL(req.url, `${req.protocol}://${req.headers.host}/`);
33
+ } catch (error) {
34
+ return next(errorUtils.getBadRequest(`Invalid URL: ${req.url} (${error})`));
35
+ }
36
+
37
+ // Rebuild the URL without hostname
38
+ req.url = url.pathname + url.search + url.hash;
39
+
40
+ if (original !== req.url) {
41
+ debug('makeURLrelative: %o -> %o', original, req.url);
42
+ } else {
43
+ debug('makeURLrelative: %o (unchanged)', original);
44
+ }
45
+ next();
46
+ }
@@ -1,10 +1,11 @@
1
1
  import { getUserAgent } from '@verdaccio/config';
2
+ import { HEADERS } from '@verdaccio/core';
2
3
 
3
4
  import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';
4
5
 
5
6
  export function userAgent(config) {
6
7
  return function (_req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
7
- res.setHeader('x-powered-by', getUserAgent(config?.user_agent));
8
+ res.setHeader(HEADERS.POWERED_BY, getUserAgent(config?.user_agent));
8
9
  next();
9
10
  };
10
11
  }
@@ -1,6 +1,6 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
- exports[`template custom body after 1`] = `
3
+ exports[`template > custom body after 1`] = `
4
4
  "
5
5
  <!DOCTYPE html>
6
6
  <html lang="en-us">
@@ -26,7 +26,7 @@ exports[`template custom body after 1`] = `
26
26
  "
27
27
  `;
28
28
 
29
- exports[`template custom body before 1`] = `
29
+ exports[`template > custom body before 1`] = `
30
30
  "
31
31
  <!DOCTYPE html>
32
32
  <html lang="en-us">
@@ -52,7 +52,7 @@ exports[`template custom body before 1`] = `
52
52
  "
53
53
  `;
54
54
 
55
- exports[`template custom render 1`] = `
55
+ exports[`template > custom render 1`] = `
56
56
  "
57
57
  <!DOCTYPE html>
58
58
  <html lang="en-us">
@@ -78,7 +78,7 @@ exports[`template custom render 1`] = `
78
78
  "
79
79
  `;
80
80
 
81
- exports[`template custom title 1`] = `
81
+ exports[`template > custom title 1`] = `
82
82
  "
83
83
  <!DOCTYPE html>
84
84
  <html lang="en-us">
@@ -104,7 +104,7 @@ exports[`template custom title 1`] = `
104
104
  "
105
105
  `;
106
106
 
107
- exports[`template meta scripts 1`] = `
107
+ exports[`template > meta scripts 1`] = `
108
108
  "
109
109
  <!DOCTYPE html>
110
110
  <html lang="en-us">
@@ -1,4 +1,5 @@
1
1
  import request from 'supertest';
2
+ import { test } from 'vitest';
2
3
 
3
4
  import { HTTP_STATUS } from '@verdaccio/core';
4
5
 
@@ -1,15 +1,15 @@
1
1
  import request from 'supertest';
2
+ import { describe, expect, test } from 'vitest';
2
3
 
3
4
  import { HTTP_STATUS } from '@verdaccio/core';
4
5
 
5
6
  import { encodeScopePackage } from '../src';
6
7
  import { getApp } from './helper';
7
8
 
8
- test('encode is json', async () => {
9
+ test('encode is json with relative path', async () => {
9
10
  const app = getApp([]);
10
11
  // @ts-ignore
11
12
  app.use(encodeScopePackage);
12
- // @ts-ignore
13
13
  app.get('/:id', (req, res) => {
14
14
  const { id } = req.params;
15
15
  res.status(HTTP_STATUS.OK).json({ id });
@@ -19,3 +19,113 @@ test('encode is json', async () => {
19
19
  expect(res.body).toEqual({ id: '@scope/foo' });
20
20
  expect(res.status).toEqual(HTTP_STATUS.OK);
21
21
  });
22
+
23
+ describe('packages requests', () => {
24
+ const app = getApp([]);
25
+ // @ts-ignore
26
+ app.use(encodeScopePackage);
27
+ app.get('/:package/:version?', (req, res) => {
28
+ const { package: pkg, version } = req.params;
29
+ res.status(HTTP_STATUS.OK).json({ package: pkg, version });
30
+ });
31
+
32
+ test('just package', async () => {
33
+ const res = await request(app).get('/foo');
34
+ expect(res.body).toEqual({ package: 'foo' });
35
+ expect(res.status).toEqual(HTTP_STATUS.OK);
36
+ });
37
+
38
+ test('package with version', async () => {
39
+ const res = await request(app).get('/foo/1.0.0');
40
+ expect(res.body).toEqual({ package: 'foo', version: '1.0.0' });
41
+ expect(res.status).toEqual(HTTP_STATUS.OK);
42
+ });
43
+
44
+ test('scoped package', async () => {
45
+ const res = await request(app).get('/@scope/foo');
46
+ expect(res.body).toEqual({ package: '@scope/foo' });
47
+ expect(res.status).toEqual(HTTP_STATUS.OK);
48
+ });
49
+
50
+ test('scoped package with version', async () => {
51
+ const res = await request(app).get('/@scope/foo/1.0.0');
52
+ expect(res.body).toEqual({ package: '@scope/foo', version: '1.0.0' });
53
+ expect(res.status).toEqual(HTTP_STATUS.OK);
54
+ });
55
+
56
+ test('scoped package with encoded path', async () => {
57
+ const res = await request(app).get('/@scope%2ffoo');
58
+ expect(res.body).toEqual({ package: '@scope/foo' });
59
+ expect(res.status).toEqual(HTTP_STATUS.OK);
60
+ });
61
+
62
+ test('scoped package and version with encoded path', async () => {
63
+ const res = await request(app).get('/@scope%2ffoo/1.0.0');
64
+ expect(res.body).toEqual({ package: '@scope/foo', version: '1.0.0' });
65
+ expect(res.status).toEqual(HTTP_STATUS.OK);
66
+ });
67
+
68
+ test('scoped package with encoded @ and path ', async () => {
69
+ const res = await request(app).get('/%40scope%2ffoo');
70
+ expect(res.body).toEqual({ package: '@scope/foo' });
71
+ expect(res.status).toEqual(HTTP_STATUS.OK);
72
+ });
73
+
74
+ test('scoped package and version with encoded @ and path', async () => {
75
+ const res = await request(app).get('/%40scope%2ffoo/1.0.0');
76
+ expect(res.body).toEqual({ package: '@scope/foo', version: '1.0.0' });
77
+ expect(res.status).toEqual(HTTP_STATUS.OK);
78
+ });
79
+
80
+ test('scoped package with encoded @', async () => {
81
+ const res = await request(app).get('/%40scope/foo');
82
+ expect(res.body).toEqual({ package: '@scope/foo' });
83
+ expect(res.status).toEqual(HTTP_STATUS.OK);
84
+ });
85
+
86
+ test('scoped package and version with encoded @', async () => {
87
+ const res = await request(app).get('/%40scope/foo/1.0.0');
88
+ expect(res.body).toEqual({ package: '@scope/foo', version: '1.0.0' });
89
+ expect(res.status).toEqual(HTTP_STATUS.OK);
90
+ });
91
+ });
92
+
93
+ describe('tarball requests', () => {
94
+ const app = getApp([]);
95
+ // @ts-ignore
96
+ app.use(encodeScopePackage);
97
+ app.get('/:package/-/:filename', (req, res) => {
98
+ const { package: pkg, filename } = req.params;
99
+ res.status(HTTP_STATUS.OK).json({ package: pkg, filename });
100
+ });
101
+
102
+ test('just package', async () => {
103
+ const res = await request(app).get('/foo/-/foo-1.2.3.tgz');
104
+ expect(res.body).toEqual({ package: 'foo', filename: 'foo-1.2.3.tgz' });
105
+ expect(res.status).toEqual(HTTP_STATUS.OK);
106
+ });
107
+
108
+ test('scoped package', async () => {
109
+ const res = await request(app).get('/@scope/foo/-/foo-1.2.3.tgz');
110
+ expect(res.body).toEqual({ package: '@scope/foo', filename: 'foo-1.2.3.tgz' });
111
+ expect(res.status).toEqual(HTTP_STATUS.OK);
112
+ });
113
+
114
+ test('scoped package with encoded path', async () => {
115
+ const res = await request(app).get('/@scope%2ffoo/-/foo-1.2.3.tgz');
116
+ expect(res.body).toEqual({ package: '@scope/foo', filename: 'foo-1.2.3.tgz' });
117
+ expect(res.status).toEqual(HTTP_STATUS.OK);
118
+ });
119
+
120
+ test('scoped package with encoded @ and path', async () => {
121
+ const res = await request(app).get('/%40scope%2ffoo/-/foo-1.2.3.tgz');
122
+ expect(res.body).toEqual({ package: '@scope/foo', filename: 'foo-1.2.3.tgz' });
123
+ expect(res.status).toEqual(HTTP_STATUS.OK);
124
+ });
125
+
126
+ test('scoped package with encoded @', async () => {
127
+ const res = await request(app).get('/%40scope/foo/-/foo-1.2.3.tgz');
128
+ expect(res.body).toEqual({ package: '@scope/foo', filename: 'foo-1.2.3.tgz' });
129
+ expect(res.status).toEqual(HTTP_STATUS.OK);
130
+ });
131
+ });
@@ -1,5 +1,6 @@
1
1
  import express from 'express';
2
2
  import request from 'supertest';
3
+ import { expect, test } from 'vitest';
3
4
 
4
5
  import { HEADERS, HTTP_STATUS } from '@verdaccio/core';
5
6
 
package/test/json.spec.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import express from 'express';
2
2
  import request from 'supertest';
3
+ import { test } from 'vitest';
3
4
 
4
5
  import { HEADERS, HTTP_STATUS } from '@verdaccio/core';
5
6
 
package/test/log.spec.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import path from 'path';
2
2
  import request from 'supertest';
3
+ import { test } from 'vitest';
3
4
 
4
5
  import { HTTP_STATUS } from '@verdaccio/core';
5
6
  import { logger, setup } from '@verdaccio/logger';
package/test/loop.spec.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import request from 'supertest';
2
+ import { test } from 'vitest';
2
3
 
3
4
  import { HTTP_STATUS } from '@verdaccio/core';
4
5
 
@@ -0,0 +1,42 @@
1
+ import request from 'supertest';
2
+ import { expect, test } from 'vitest';
3
+
4
+ import { HEADERS, HTTP_STATUS } from '@verdaccio/core';
5
+
6
+ import { makeURLrelative } from '../src';
7
+ import { getApp } from './helper';
8
+
9
+ const testHosts = [
10
+ 'localhost:4873', // with port
11
+ 'myregistry.com', // no port
12
+ '42.42.42.42', // ip
13
+ '[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443', // ip6
14
+ ];
15
+
16
+ test.each([testHosts])('remove host from url', async (host) => {
17
+ const app = getApp([]);
18
+ // @ts-ignore
19
+ app.use(makeURLrelative);
20
+ app.get('/:id', (req, res) => {
21
+ const { id } = req.params;
22
+ res.status(HTTP_STATUS.OK).json({ id, url: req.url });
23
+ });
24
+
25
+ const res = await request(app).get('/foo').set(HEADERS.HOST, host);
26
+ expect(res.body).toEqual({ id: 'foo', url: '/foo' });
27
+ expect(res.status).toEqual(HTTP_STATUS.OK);
28
+ });
29
+
30
+ test('invalid url', async () => {
31
+ const app = getApp([]);
32
+ // @ts-ignore
33
+ app.use(makeURLrelative);
34
+ app.get('/:id', (req, res) => {
35
+ const { id } = req.params;
36
+ res.status(HTTP_STATUS.OK).json({ id });
37
+ });
38
+
39
+ const res = await request(app).get('/foo').set(HEADERS.HOST, 'invalid::host');
40
+ expect(res.status).toEqual(HTTP_STATUS.BAD_REQUEST);
41
+ expect(res.text).toContain('Invalid URL');
42
+ });
@@ -1,3 +1,5 @@
1
+ import { describe, expect, test } from 'vitest';
2
+
1
3
  import { getManifestValue } from '../src/middlewares/web/utils/manifest';
2
4
 
3
5
  const manifest = require('./partials/manifest/manifest.json');
@@ -1,5 +1,6 @@
1
1
  import mime from 'mime';
2
2
  import request from 'supertest';
3
+ import { test } from 'vitest';
3
4
 
4
5
  import { HEADERS, HTTP_STATUS } from '@verdaccio/core';
5
6
 
@@ -1,4 +1,5 @@
1
1
  import request from 'supertest';
2
+ import { describe, test } from 'vitest';
2
3
 
3
4
  import { HTTP_STATUS } from '@verdaccio/core';
4
5
 
@@ -2,6 +2,7 @@ import express from 'express';
2
2
  import { JSDOM } from 'jsdom';
3
3
  import path from 'path';
4
4
  import supertest from 'supertest';
5
+ import { describe, expect, test } from 'vitest';
5
6
 
6
7
  import { HEADERS, HEADER_TYPE, HTTP_STATUS } from '@verdaccio/core';
7
8
  import { setup } from '@verdaccio/logger';
@@ -1,4 +1,5 @@
1
1
  import request from 'supertest';
2
+ import { expect, test } from 'vitest';
2
3
 
3
4
  import { HEADERS, HTTP_STATUS } from '@verdaccio/core';
4
5
 
@@ -0,0 +1,3 @@
1
+ {
2
+ runtime: '';
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ vendors: '';
3
+ }
@@ -1,3 +1,5 @@
1
+ import { describe, expect, test } from 'vitest';
2
+
1
3
  import template from '../src/middlewares/web/utils/template';
2
4
 
3
5
  const manifest = require('./partials/manifest/manifest.json');
@@ -1,3 +1,5 @@
1
+ import { describe, expect, test } from 'vitest';
2
+
1
3
  import { validatePrimaryColor } from '../src/middlewares/web/utils/web-utils';
2
4
 
3
5
  describe('Utilities', () => {
@@ -1,4 +1,5 @@
1
1
  import request from 'supertest';
2
+ import { describe, test } from 'vitest';
2
3
 
3
4
  import { HTTP_STATUS } from '@verdaccio/core';
4
5
 
package/jest.config.js DELETED
@@ -1,12 +0,0 @@
1
- const config = require('../../jest/config');
2
-
3
- module.exports = Object.assign({}, config, {
4
- coverageThreshold: {
5
- global: {
6
- lines: 67,
7
- functions: 70,
8
- branches: 55,
9
- statements: 67,
10
- },
11
- },
12
- });
@@ -1,3 +0,0 @@
1
- {
2
- 'vendors': '';
3
- }