@verdaccio/web 8.1.0-next-8.6 → 8.1.0-next-8.8

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # @verdaccio/web
2
2
 
3
+ ## 8.1.0-next-8.8
4
+
5
+ ### Patch Changes
6
+
7
+ - a7afdc7: feat: show version-specific readmes in web ui
8
+ - Updated dependencies [0588605]
9
+ - Updated dependencies [ca91b9a]
10
+ - @verdaccio/config@8.0.0-next-8.8
11
+ - @verdaccio/auth@8.0.0-next-8.8
12
+ - @verdaccio/loaders@8.0.0-next-8.4
13
+ - @verdaccio/middleware@8.0.0-next-8.8
14
+ - @verdaccio/store@8.0.0-next-8.8
15
+ - @verdaccio/core@8.0.0-next-8.8
16
+ - @verdaccio/tarball@13.0.0-next-8.8
17
+ - @verdaccio/url@13.0.0-next-8.8
18
+ - @verdaccio/logger@8.0.0-next-8.8
19
+ - @verdaccio/utils@8.1.0-next-8.8
20
+
21
+ ## 8.1.0-next-8.7
22
+
23
+ ### Patch Changes
24
+
25
+ - 139861e: fix: crashes with path-to-regexp v0.1.12 express
26
+ - Updated dependencies [589ea7f]
27
+ - Updated dependencies [139861e]
28
+ - @verdaccio/tarball@13.0.0-next-8.7
29
+ - @verdaccio/core@8.0.0-next-8.7
30
+ - @verdaccio/utils@8.1.0-next-8.7
31
+ - @verdaccio/middleware@8.0.0-next-8.7
32
+ - @verdaccio/store@8.0.0-next-8.7
33
+ - @verdaccio/auth@8.0.0-next-8.7
34
+ - @verdaccio/config@8.0.0-next-8.7
35
+ - @verdaccio/url@13.0.0-next-8.7
36
+ - @verdaccio/loaders@8.0.0-next-8.4
37
+ - @verdaccio/logger@8.0.0-next-8.7
38
+
3
39
  ## 8.1.0-next-8.6
4
40
 
5
41
  ### Patch Changes
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 Verdaccio contributors
3
+ Copyright (c) 2025 Verdaccio contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -103,7 +103,7 @@ function addPackageWebApi(storage, auth, config) {
103
103
  }
104
104
 
105
105
  // Get list of all visible package
106
- pkgRouter.get('/packages', async function (req, res, next) {
106
+ pkgRouter.get(_middleware.WebUrls.packages_all, async function (req, res, next) {
107
107
  debug('hit package web api %o');
108
108
  try {
109
109
  const localPackages = await storage.getLocalDatabase();
@@ -1 +1 @@
1
- {"version":3,"file":"package.js","names":["_debug","_interopRequireDefault","require","_express","_lodash","_logger","_middleware","_tarball","_utils","_webUtils","e","__esModule","default","getOrder","order","debug","buildDebug","addPackageWebApi","storage","auth","config","isLoginEnabled","web","login","pkgRouter","Router","anonymousRemoteUser","name","undefined","real_groups","groups","checkAllow","remoteUser","Promise","resolve","reject","allow_access","packageName","err","allowed","processPackages","packages","req","permissions","packagesToProcess","slice","pkg","pkgCopy","author","formatAuthor","remote_user","avatar","generateGravatarUrl","email","gravatar","_","isNil","dist","isNull","tarball","getLocalRegistryTarballUri","protocol","headers","host","hostname","url_prefix","push","logger","error","get","res","next","localPackages","getLocalDatabase","sort_packages","pkgs","sortByName","_default","exports"],"sources":["../../src/api/package.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Router } from 'express';\nimport _ from 'lodash';\n\nimport { Auth } from '@verdaccio/auth';\nimport { logger } from '@verdaccio/logger';\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '@verdaccio/middleware';\nimport { Storage } from '@verdaccio/store';\nimport { getLocalRegistryTarballUri } from '@verdaccio/tarball';\nimport { Config, RemoteUser, Version } from '@verdaccio/types';\nimport { formatAuthor, generateGravatarUrl } from '@verdaccio/utils';\n\nimport { sortByName } from '../web-utils';\n\nexport { $RequestExtend, $ResponseExtend, $NextFunctionVer }; // Was required by other packages\n\nconst getOrder = (order = 'asc') => {\n return order === 'asc';\n};\n\nconst debug = buildDebug('verdaccio:web:api:package');\n\nfunction addPackageWebApi(storage: Storage, auth: Auth, config: Config): Router {\n const isLoginEnabled = config?.web?.login === true ?? true;\n const pkgRouter = Router(); /* eslint new-cap: 0 */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const anonymousRemoteUser: RemoteUser = {\n name: undefined,\n real_groups: [],\n groups: [],\n };\n\n debug('initialized package web api');\n const checkAllow = (name: string, remoteUser: RemoteUser): Promise<boolean> =>\n new Promise((resolve, reject): void => {\n debug('is login disabled %o', isLoginEnabled);\n // FIXME: this logic does not work, review\n // const remoteUserAccess = !isLoginEnabled ? anonymousRemoteUser : remoteUser;\n try {\n auth.allow_access({ packageName: name }, remoteUser, (err, allowed): void => {\n if (err) {\n resolve(false);\n }\n return resolve(allowed as boolean);\n });\n } catch (err: any) {\n reject(err);\n }\n });\n\n async function processPackages(packages: Version[] = [], req): Promise<Version[]> {\n const permissions: Version[] = [];\n const packagesToProcess = packages.slice();\n debug('process packages %o', packagesToProcess);\n for (const pkg of packagesToProcess) {\n const pkgCopy = { ...pkg };\n pkgCopy.author = formatAuthor(pkg.author);\n try {\n if (await checkAllow(pkg.name, req.remote_user)) {\n if (config.web) {\n // @ts-ignore\n pkgCopy.author.avatar = generateGravatarUrl(pkgCopy.author.email, config.web.gravatar);\n }\n // convert any remote dist to a local reference\n // eg: if the dist points to npmjs, switch to localhost:4873/prefix/etc.tar.gz\n if (!_.isNil(pkgCopy.dist) && !_.isNull(pkgCopy.dist.tarball)) {\n pkgCopy.dist.tarball = getLocalRegistryTarballUri(\n pkgCopy.dist.tarball,\n pkg.name,\n { protocol: req.protocol, headers: req.headers as any, host: req.hostname },\n config?.url_prefix\n );\n }\n permissions.push(pkgCopy);\n }\n } catch (err: any) {\n debug('process packages error %o', err);\n logger.error(\n { name: pkg.name, error: err },\n 'permission process for @{name} has failed: @{error}'\n );\n throw err;\n }\n }\n\n return permissions;\n }\n\n // Get list of all visible package\n pkgRouter.get(\n '/packages',\n async function (\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n ): Promise<void> {\n debug('hit package web api %o');\n\n try {\n const localPackages: Version[] = await storage.getLocalDatabase();\n\n const order = getOrder(config?.web?.sort_packages);\n debug('order %o', order);\n const pkgs = await processPackages(localPackages, req);\n next(sortByName(pkgs, order));\n } catch (error: any) {\n next(error);\n }\n }\n );\n\n return pkgRouter;\n}\n\nexport default addPackageWebApi;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"package.js","names":["_debug","_interopRequireDefault","require","_express","_lodash","_logger","_middleware","_tarball","_utils","_webUtils","e","__esModule","default","getOrder","order","debug","buildDebug","addPackageWebApi","storage","auth","config","isLoginEnabled","web","login","pkgRouter","Router","anonymousRemoteUser","name","undefined","real_groups","groups","checkAllow","remoteUser","Promise","resolve","reject","allow_access","packageName","err","allowed","processPackages","packages","req","permissions","packagesToProcess","slice","pkg","pkgCopy","author","formatAuthor","remote_user","avatar","generateGravatarUrl","email","gravatar","_","isNil","dist","isNull","tarball","getLocalRegistryTarballUri","protocol","headers","host","hostname","url_prefix","push","logger","error","get","WebUrls","packages_all","res","next","localPackages","getLocalDatabase","sort_packages","pkgs","sortByName","_default","exports"],"sources":["../../src/api/package.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Router } from 'express';\nimport _ from 'lodash';\n\nimport { Auth } from '@verdaccio/auth';\nimport { logger } from '@verdaccio/logger';\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '@verdaccio/middleware';\nimport { WebUrls } from '@verdaccio/middleware';\nimport { Storage } from '@verdaccio/store';\nimport { getLocalRegistryTarballUri } from '@verdaccio/tarball';\nimport { Config, RemoteUser, Version } from '@verdaccio/types';\nimport { formatAuthor, generateGravatarUrl } from '@verdaccio/utils';\n\nimport { sortByName } from '../web-utils';\n\nexport { $RequestExtend, $ResponseExtend, $NextFunctionVer }; // Was required by other packages\n\nconst getOrder = (order = 'asc') => {\n return order === 'asc';\n};\n\nconst debug = buildDebug('verdaccio:web:api:package');\n\nfunction addPackageWebApi(storage: Storage, auth: Auth, config: Config): Router {\n const isLoginEnabled = config?.web?.login === true ?? true;\n const pkgRouter = Router(); /* eslint new-cap: 0 */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const anonymousRemoteUser: RemoteUser = {\n name: undefined,\n real_groups: [],\n groups: [],\n };\n\n debug('initialized package web api');\n const checkAllow = (name: string, remoteUser: RemoteUser): Promise<boolean> =>\n new Promise((resolve, reject): void => {\n debug('is login disabled %o', isLoginEnabled);\n // FIXME: this logic does not work, review\n // const remoteUserAccess = !isLoginEnabled ? anonymousRemoteUser : remoteUser;\n try {\n auth.allow_access({ packageName: name }, remoteUser, (err, allowed): void => {\n if (err) {\n resolve(false);\n }\n return resolve(allowed as boolean);\n });\n } catch (err: any) {\n reject(err);\n }\n });\n\n async function processPackages(packages: Version[] = [], req): Promise<Version[]> {\n const permissions: Version[] = [];\n const packagesToProcess = packages.slice();\n debug('process packages %o', packagesToProcess);\n for (const pkg of packagesToProcess) {\n const pkgCopy = { ...pkg };\n pkgCopy.author = formatAuthor(pkg.author);\n try {\n if (await checkAllow(pkg.name, req.remote_user)) {\n if (config.web) {\n // @ts-ignore\n pkgCopy.author.avatar = generateGravatarUrl(pkgCopy.author.email, config.web.gravatar);\n }\n // convert any remote dist to a local reference\n // eg: if the dist points to npmjs, switch to localhost:4873/prefix/etc.tar.gz\n if (!_.isNil(pkgCopy.dist) && !_.isNull(pkgCopy.dist.tarball)) {\n pkgCopy.dist.tarball = getLocalRegistryTarballUri(\n pkgCopy.dist.tarball,\n pkg.name,\n { protocol: req.protocol, headers: req.headers as any, host: req.hostname },\n config?.url_prefix\n );\n }\n permissions.push(pkgCopy);\n }\n } catch (err: any) {\n debug('process packages error %o', err);\n logger.error(\n { name: pkg.name, error: err },\n 'permission process for @{name} has failed: @{error}'\n );\n throw err;\n }\n }\n\n return permissions;\n }\n\n // Get list of all visible package\n pkgRouter.get(\n WebUrls.packages_all,\n async function (\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n ): Promise<void> {\n debug('hit package web api %o');\n\n try {\n const localPackages: Version[] = await storage.getLocalDatabase();\n\n const order = getOrder(config?.web?.sort_packages);\n debug('order %o', order);\n const pkgs = await processPackages(localPackages, req);\n next(sortByName(pkgs, order));\n } catch (error: any) {\n next(error);\n }\n }\n );\n\n return pkgRouter;\n}\n\nexport default addPackageWebApi;\n"],"mappings":"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","ignoreList":[]}
@@ -27,10 +27,13 @@ var _express = require("express");
27
27
  var _core = require("@verdaccio/core");
28
28
  var _logger = require("@verdaccio/logger");
29
29
  var _middleware = require("@verdaccio/middleware");
30
+ var _utils = require("@verdaccio/utils");
30
31
  var _webUtils = require("../web-utils");
31
32
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
32
33
  // Was required by other packages
33
34
 
35
+ // Was required by other packages
36
+
34
37
  // TODO: review this type, should be on @verdacid/types
35
38
 
36
39
  const NOT_README_FOUND = exports.NOT_README_FOUND = 'ERROR: No README data found!';
@@ -45,6 +48,24 @@ const getReadme = readme => {
45
48
  return readme;
46
49
  }
47
50
  };
51
+ const getReadmeFromManifest = (manifest, v) => {
52
+ let id;
53
+ let readme;
54
+ if (typeof v === 'string' && (0, _utils.isVersionValid)(manifest, v)) {
55
+ id = 'version';
56
+ readme = manifest.versions[v].readme;
57
+ }
58
+ if (!readme && (0, _utils.isVersionValid)(manifest, manifest[_core.DIST_TAGS]?.latest)) {
59
+ id = 'latest';
60
+ readme = manifest.versions[manifest[_core.DIST_TAGS].latest].readme;
61
+ }
62
+ if (!readme && manifest.readme) {
63
+ id = 'root';
64
+ readme = manifest.readme;
65
+ }
66
+ debug('readme: %o %o', v, id);
67
+ return readme;
68
+ };
48
69
  function addReadmeWebApi(storage, auth) {
49
70
  debug('initialized readme web api');
50
71
  const can = (0, _middleware.allow)(auth, {
@@ -53,7 +74,7 @@ function addReadmeWebApi(storage, auth) {
53
74
  });
54
75
  const pkgRouter = (0, _express.Router)(); /* eslint new-cap: 0 */
55
76
 
56
- pkgRouter.get('/package/readme/:scope(@[^/]+)?/:package/:version?', can('access'), async function (req, res, next) {
77
+ pkgRouter.get([_middleware.WebUrls.readme_package_scoped_version, _middleware.WebUrls.readme_package_version], can('access'), async function (req, res, next) {
57
78
  debug('readme hit');
58
79
  const rawScope = req.params.scope; // May include '@'
59
80
  const scope = rawScope ? rawScope.slice(1) : null; // Remove '@' if present
@@ -75,7 +96,11 @@ function addReadmeWebApi(storage, auth) {
75
96
  });
76
97
  debug('readme pkg %o', manifest?.name);
77
98
  res.set(_core.HEADER_TYPE.CONTENT_TYPE, _core.HEADERS.TEXT_PLAIN_UTF8);
78
- next(getReadme(manifest.readme));
99
+ const {
100
+ v
101
+ } = req.query;
102
+ const readme = getReadmeFromManifest(manifest, v);
103
+ next(getReadme(readme));
79
104
  } catch (err) {
80
105
  next(err);
81
106
  }
@@ -1 +1 @@
1
- {"version":3,"file":"readme.js","names":["_debug","_interopRequireDefault","require","_express","_core","_logger","_middleware","_webUtils","e","__esModule","default","NOT_README_FOUND","exports","debug","buildDebug","getReadme","readme","length","addReadmeWebApi","storage","auth","can","allow","beforeAll","a","b","logger","trace","afterAll","pkgRouter","Router","get","req","res","next","rawScope","params","scope","slice","name","addScope","package","requestOptions","protocol","headers","host","remoteAddress","socket","manifest","getPackageByOptions","uplinksLook","abbreviated","set","HEADER_TYPE","CONTENT_TYPE","HEADERS","TEXT_PLAIN_UTF8","err","_default"],"sources":["../../src/api/readme.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Router } from 'express';\n\nimport { Auth } from '@verdaccio/auth';\nimport { HEADERS, HEADER_TYPE } from '@verdaccio/core';\nimport { logger } from '@verdaccio/logger';\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend, allow } from '@verdaccio/middleware';\nimport { Storage } from '@verdaccio/store';\nimport { Manifest } from '@verdaccio/types';\n\nimport { AuthorAvatar, addScope } from '../web-utils';\n\nexport { $RequestExtend, $ResponseExtend, $NextFunctionVer }; // Was required by other packages\n\n// TODO: review this type, should be on @verdacid/types\nexport type PackageExt = Manifest & { author: AuthorAvatar; dist?: { tarball: string } };\nexport const NOT_README_FOUND = 'ERROR: No README data found!';\nconst debug = buildDebug('verdaccio:web:api:readme');\nconst getReadme = (readme) => {\n if (typeof readme === 'string' && readme.length === 0) {\n return NOT_README_FOUND;\n }\n if (typeof readme !== 'string') {\n return NOT_README_FOUND;\n } else {\n return readme;\n }\n};\n\nfunction addReadmeWebApi(storage: Storage, auth: Auth): Router {\n debug('initialized readme web api');\n const can = allow(auth, {\n beforeAll: (a, b) => logger.trace(a, b),\n afterAll: (a, b) => logger.trace(a, b),\n });\n const pkgRouter = Router(); /* eslint new-cap: 0 */\n\n pkgRouter.get(\n '/package/readme/:scope(@[^/]+)?/:package/:version?',\n can('access'),\n async function (\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n ): Promise<void> {\n debug('readme hit');\n const rawScope = req.params.scope; // May include '@'\n const scope = rawScope ? rawScope.slice(1) : null; // Remove '@' if present\n const name = scope ? addScope(scope, req.params.package) : req.params.package;\n debug('readme name %o', name);\n const requestOptions = {\n protocol: req.protocol,\n headers: req.headers as any,\n // FIXME: if we migrate to req.hostname, the port is not longer included.\n host: req.host,\n remoteAddress: req.socket.remoteAddress,\n };\n try {\n const manifest = (await storage.getPackageByOptions({\n name,\n uplinksLook: true,\n abbreviated: false,\n requestOptions,\n })) as Manifest;\n debug('readme pkg %o', manifest?.name);\n res.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_PLAIN_UTF8);\n next(getReadme(manifest.readme));\n } catch (err) {\n next(err);\n }\n }\n );\n return pkgRouter;\n}\n\nexport default addReadmeWebApi;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"readme.js","names":["_debug","_interopRequireDefault","require","_express","_core","_logger","_middleware","_utils","_webUtils","e","__esModule","default","NOT_README_FOUND","exports","debug","buildDebug","getReadme","readme","length","getReadmeFromManifest","manifest","v","id","isVersionValid","versions","DIST_TAGS","latest","addReadmeWebApi","storage","auth","can","allow","beforeAll","a","b","logger","trace","afterAll","pkgRouter","Router","get","WebUrls","readme_package_scoped_version","readme_package_version","req","res","next","rawScope","params","scope","slice","name","addScope","package","requestOptions","protocol","headers","host","remoteAddress","socket","getPackageByOptions","uplinksLook","abbreviated","set","HEADER_TYPE","CONTENT_TYPE","HEADERS","TEXT_PLAIN_UTF8","query","err","_default"],"sources":["../../src/api/readme.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Router } from 'express';\n\nimport { Auth } from '@verdaccio/auth';\nimport { DIST_TAGS, HEADERS, HEADER_TYPE } from '@verdaccio/core';\nimport { logger } from '@verdaccio/logger';\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend, allow } from '@verdaccio/middleware';\n// Was required by other packages\nimport { WebUrls } from '@verdaccio/middleware';\nimport { Storage } from '@verdaccio/store';\nimport { Manifest } from '@verdaccio/types';\nimport { isVersionValid } from '@verdaccio/utils';\n\nimport { AuthorAvatar, addScope } from '../web-utils';\n\nexport { $RequestExtend, $ResponseExtend, $NextFunctionVer }; // Was required by other packages\n\n// TODO: review this type, should be on @verdacid/types\nexport type PackageExt = Manifest & { author: AuthorAvatar; dist?: { tarball: string } };\nexport const NOT_README_FOUND = 'ERROR: No README data found!';\nconst debug = buildDebug('verdaccio:web:api:readme');\n\nconst getReadme = (readme) => {\n if (typeof readme === 'string' && readme.length === 0) {\n return NOT_README_FOUND;\n }\n if (typeof readme !== 'string') {\n return NOT_README_FOUND;\n } else {\n return readme;\n }\n};\n\nconst getReadmeFromManifest = (manifest: Manifest, v?: any): string | undefined => {\n let id;\n let readme;\n if (typeof v === 'string' && isVersionValid(manifest, v)) {\n id = 'version';\n readme = manifest.versions[v].readme;\n }\n if (!readme && isVersionValid(manifest, manifest[DIST_TAGS]?.latest)) {\n id = 'latest';\n readme = manifest.versions[manifest[DIST_TAGS].latest].readme;\n }\n if (!readme && manifest.readme) {\n id = 'root';\n readme = manifest.readme;\n }\n debug('readme: %o %o', v, id);\n return readme;\n};\n\nfunction addReadmeWebApi(storage: Storage, auth: Auth): Router {\n debug('initialized readme web api');\n const can = allow(auth, {\n beforeAll: (a, b) => logger.trace(a, b),\n afterAll: (a, b) => logger.trace(a, b),\n });\n const pkgRouter = Router(); /* eslint new-cap: 0 */\n\n pkgRouter.get(\n [WebUrls.readme_package_scoped_version, WebUrls.readme_package_version],\n can('access'),\n async function (\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n ): Promise<void> {\n debug('readme hit');\n const rawScope = req.params.scope; // May include '@'\n const scope = rawScope ? rawScope.slice(1) : null; // Remove '@' if present\n const name = scope ? addScope(scope, req.params.package) : req.params.package;\n debug('readme name %o', name);\n const requestOptions = {\n protocol: req.protocol,\n headers: req.headers as any,\n // FIXME: if we migrate to req.hostname, the port is not longer included.\n host: req.host,\n remoteAddress: req.socket.remoteAddress,\n };\n try {\n const manifest = (await storage.getPackageByOptions({\n name,\n uplinksLook: true,\n abbreviated: false,\n requestOptions,\n })) as Manifest;\n debug('readme pkg %o', manifest?.name);\n res.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_PLAIN_UTF8);\n const { v } = req.query;\n const readme = getReadmeFromManifest(manifest, v);\n next(getReadme(readme));\n } catch (err) {\n next(err);\n }\n }\n );\n return pkgRouter;\n}\n\nexport default addReadmeWebApi;\n"],"mappings":"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","ignoreList":[]}
@@ -9,6 +9,7 @@ var _express = require("express");
9
9
  var _lodash = _interopRequireDefault(require("lodash"));
10
10
  var _url = require("url");
11
11
  var _core = require("@verdaccio/core");
12
+ var _middleware = require("@verdaccio/middleware");
12
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
14
  const debug = (0, _debug.default)('verdaccio:web:api:search');
14
15
  function checkAccess(pkg, auth, remoteUser) {
@@ -33,7 +34,7 @@ function checkAccess(pkg, auth, remoteUser) {
33
34
  }
34
35
  function addSearchWebApi(storage, auth) {
35
36
  const router = (0, _express.Router)(); /* eslint new-cap: 0 */
36
- router.get('/search/:anything', async function (req, res, next) {
37
+ router.get(_middleware.WebUrls.search, async function (req, res, next) {
37
38
  try {
38
39
  let data;
39
40
  const abort = new AbortController();
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","names":["_debug","_interopRequireDefault","require","_express","_lodash","_url","_core","e","__esModule","default","debug","buildDebug","checkAccess","pkg","auth","remoteUser","Promise","resolve","reject","allow_access","packageName","package","name","err","allowed","status","String","match","addSearchWebApi","storage","router","Router","get","req","res","next","data","abort","AbortController","socket","on","text","params","anything","size","from","query","maintenance","popularity","quality","urlParams","URLSearchParams","search","url","toString","checkAccessPromises","all","map","pkgItem","remote_user","final","filter","i","_","isNull","slice","errorUtils","getInternalError","message","_default","exports"],"sources":["../../src/api/search.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Router } from 'express';\nimport _ from 'lodash';\nimport { URLSearchParams } from 'url';\n\nimport { Auth } from '@verdaccio/auth';\nimport { errorUtils, searchUtils } from '@verdaccio/core';\nimport { SearchQuery } from '@verdaccio/core/src/search-utils';\nimport { Storage } from '@verdaccio/store';\nimport { Manifest } from '@verdaccio/types';\n\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend } from './package';\n\nconst debug = buildDebug('verdaccio:web:api:search');\n\nfunction checkAccess(pkg: any, auth: any, remoteUser): Promise<Manifest | null> {\n return new Promise((resolve, reject) => {\n auth.allow_access({ packageName: pkg?.package?.name }, remoteUser, function (err, allowed) {\n if (err) {\n if (err.status && String(err.status).match(/^4\\d\\d$/)) {\n // auth plugin returns 4xx user error,\n // that's equivalent of !allowed basically\n allowed = false;\n return resolve(null);\n } else {\n reject(err);\n }\n } else {\n return resolve(allowed ? pkg : null);\n }\n });\n });\n}\n\nfunction addSearchWebApi(storage: Storage, auth: Auth): Router {\n const router = Router(); /* eslint new-cap: 0 */\n router.get(\n '/search/:anything',\n async function (\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n ): Promise<void> {\n try {\n let data;\n const abort = new AbortController();\n req.socket.on('close', function () {\n debug('search web aborted');\n abort.abort();\n });\n const text: string = (req.params.anything as string) ?? '';\n // These values are declared as optimal by npm cli\n // FUTURE: could be overwritten by ui settings.\n const size = 20;\n const from = 0;\n const query: SearchQuery = {\n from: 0,\n maintenance: 0.5,\n popularity: 0.98,\n quality: 0.65,\n size: 20,\n text,\n };\n // @ts-ignore\n const urlParams = new URLSearchParams(query);\n debug('search web init');\n data = await storage?.search({\n query,\n url: `/-/v1/search?${urlParams.toString()}`,\n abort,\n });\n const checkAccessPromises: searchUtils.SearchItemPkg[] = await Promise.all(\n data.map((pkgItem) => {\n return checkAccess(pkgItem, auth, req.remote_user);\n })\n );\n\n const final: searchUtils.SearchItemPkg[] = checkAccessPromises\n .filter((i) => !_.isNull(i))\n .slice(from, size);\n\n next(final);\n } catch (err: any) {\n next(errorUtils.getInternalError(err.message));\n }\n }\n );\n return router;\n}\n\nexport default addSearchWebApi;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"search.js","names":["_debug","_interopRequireDefault","require","_express","_lodash","_url","_core","_middleware","e","__esModule","default","debug","buildDebug","checkAccess","pkg","auth","remoteUser","Promise","resolve","reject","allow_access","packageName","package","name","err","allowed","status","String","match","addSearchWebApi","storage","router","Router","get","WebUrls","search","req","res","next","data","abort","AbortController","socket","on","text","params","anything","size","from","query","maintenance","popularity","quality","urlParams","URLSearchParams","url","toString","checkAccessPromises","all","map","pkgItem","remote_user","final","filter","i","_","isNull","slice","errorUtils","getInternalError","message","_default","exports"],"sources":["../../src/api/search.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Router } from 'express';\nimport _ from 'lodash';\nimport { URLSearchParams } from 'url';\n\nimport { Auth } from '@verdaccio/auth';\nimport { errorUtils, searchUtils } from '@verdaccio/core';\nimport { SearchQuery } from '@verdaccio/core/src/search-utils';\nimport { WebUrls } from '@verdaccio/middleware';\nimport { Storage } from '@verdaccio/store';\nimport { Manifest } from '@verdaccio/types';\n\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend } from './package';\n\nconst debug = buildDebug('verdaccio:web:api:search');\n\nfunction checkAccess(pkg: any, auth: any, remoteUser): Promise<Manifest | null> {\n return new Promise((resolve, reject) => {\n auth.allow_access({ packageName: pkg?.package?.name }, remoteUser, function (err, allowed) {\n if (err) {\n if (err.status && String(err.status).match(/^4\\d\\d$/)) {\n // auth plugin returns 4xx user error,\n // that's equivalent of !allowed basically\n allowed = false;\n return resolve(null);\n } else {\n reject(err);\n }\n } else {\n return resolve(allowed ? pkg : null);\n }\n });\n });\n}\n\nfunction addSearchWebApi(storage: Storage, auth: Auth): Router {\n const router = Router(); /* eslint new-cap: 0 */\n router.get(\n WebUrls.search,\n async function (\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n ): Promise<void> {\n try {\n let data;\n const abort = new AbortController();\n req.socket.on('close', function () {\n debug('search web aborted');\n abort.abort();\n });\n const text: string = (req.params.anything as string) ?? '';\n // These values are declared as optimal by npm cli\n // FUTURE: could be overwritten by ui settings.\n const size = 20;\n const from = 0;\n const query: SearchQuery = {\n from: 0,\n maintenance: 0.5,\n popularity: 0.98,\n quality: 0.65,\n size: 20,\n text,\n };\n // @ts-ignore\n const urlParams = new URLSearchParams(query);\n debug('search web init');\n data = await storage?.search({\n query,\n url: `/-/v1/search?${urlParams.toString()}`,\n abort,\n });\n const checkAccessPromises: searchUtils.SearchItemPkg[] = await Promise.all(\n data.map((pkgItem) => {\n return checkAccess(pkgItem, auth, req.remote_user);\n })\n );\n\n const final: searchUtils.SearchItemPkg[] = checkAccessPromises\n .filter((i) => !_.isNull(i))\n .slice(from, size);\n\n next(final);\n } catch (err: any) {\n next(errorUtils.getInternalError(err.message));\n }\n }\n );\n return router;\n}\n\nexport default addSearchWebApi;\n"],"mappings":"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","ignoreList":[]}
@@ -33,6 +33,8 @@ var _webUtils = require("../web-utils");
33
33
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
34
34
  // Was required by other packages
35
35
 
36
+ // Was required by other packages
37
+
36
38
  const debug = (0, _debug.default)('verdaccio:web:api:sidebar');
37
39
  function addSidebarWebApi(config, storage, auth) {
38
40
  debug('initialized sidebar web api');
@@ -42,7 +44,7 @@ function addSidebarWebApi(config, storage, auth) {
42
44
  afterAll: (a, b) => _logger.logger.trace(a, b)
43
45
  });
44
46
  // Get package sidebar
45
- router.get('/sidebar/:scope(@[^/]+)?/:package', can('access'), async function (req, res, next) {
47
+ router.get([_middleware.WebUrls.sidebar_scopped_package, _middleware.WebUrls.sidebar_package], can('access'), async function (req, res, next) {
46
48
  const rawScope = req.params.scope; // May include '@'
47
49
  const scope = rawScope ? rawScope.slice(1) : null; // Remove '@' if present
48
50
  const name = scope ? (0, _webUtils.addScope)(scope, req.params.package) : req.params.package;
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar.js","names":["_debug","_interopRequireDefault","require","_express","_core","_logger","_middleware","_tarball","_utils","_webUtils","e","__esModule","default","debug","buildDebug","addSidebarWebApi","config","storage","auth","router","Router","can","allow","beforeAll","a","b","logger","trace","afterAll","get","req","res","next","rawScope","params","scope","slice","name","addScope","package","requestOptions","protocol","headers","host","remoteAddress","socket","info","getPackageByOptions","uplinksLook","keepUpLinkData","v","query","sideBarInfo","versions","convertDistRemoteToLocalTarballUrls","hostname","url_prefix","isVersionValid","latest","author","formatAuthor","DIST_TAGS","deleteProperties","authorAvatar","web","addGravatarSupport","gravatar","err","status","HTTP_STATUS","NOT_FOUND","end","_default","exports"],"sources":["../../src/api/sidebar.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Router } from 'express';\n\nimport { Auth } from '@verdaccio/auth';\nimport { DIST_TAGS, HTTP_STATUS } from '@verdaccio/core';\nimport { logger } from '@verdaccio/logger';\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend, allow } from '@verdaccio/middleware';\nimport { Storage } from '@verdaccio/store';\nimport { convertDistRemoteToLocalTarballUrls } from '@verdaccio/tarball';\nimport { Config, Manifest, Version } from '@verdaccio/types';\nimport { addGravatarSupport, formatAuthor, isVersionValid } from '@verdaccio/utils';\n\nimport { AuthorAvatar, addScope, deleteProperties } from '../web-utils';\n\nexport { $RequestExtend, $ResponseExtend, $NextFunctionVer }; // Was required by other packages\n\nexport type PackageExt = Manifest & { author: AuthorAvatar; dist?: { tarball: string } };\n\nexport type $SidebarPackage = Manifest & { latest: Version };\nconst debug = buildDebug('verdaccio:web:api:sidebar');\n\nfunction addSidebarWebApi(config: Config, storage: Storage, auth: Auth): Router {\n debug('initialized sidebar web api');\n const router = Router(); /* eslint new-cap: 0 */\n const can = allow(auth, {\n beforeAll: (a, b) => logger.trace(a, b),\n afterAll: (a, b) => logger.trace(a, b),\n });\n // Get package sidebar\n router.get(\n '/sidebar/:scope(@[^/]+)?/:package',\n can('access'),\n async function (\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n ): Promise<void> {\n const rawScope = req.params.scope; // May include '@'\n const scope = rawScope ? rawScope.slice(1) : null; // Remove '@' if present\n const name: string = scope ? addScope(scope, req.params.package) : req.params.package;\n const requestOptions = {\n protocol: req.protocol,\n headers: req.headers as any,\n // FIXME: if we migrate to req.hostname, the port is not longer included.\n host: req.host,\n remoteAddress: req.socket.remoteAddress,\n };\n try {\n const info = (await storage.getPackageByOptions({\n name,\n uplinksLook: true,\n keepUpLinkData: true,\n requestOptions,\n })) as Manifest;\n const { v } = req.query;\n let sideBarInfo = { ...info };\n sideBarInfo.versions = convertDistRemoteToLocalTarballUrls(\n info,\n { protocol: req.protocol, headers: req.headers as any, host: req.hostname },\n config.url_prefix\n ).versions;\n // TODO: review this implementation\n if (typeof v === 'string' && isVersionValid(info, v)) {\n // @ts-ignore\n sideBarInfo.latest = sideBarInfo.versions[v];\n // @ts-ignore\n sideBarInfo.latest.author = formatAuthor(sideBarInfo.latest.author);\n } else {\n // @ts-ignore\n sideBarInfo.latest = sideBarInfo.versions[info[DIST_TAGS].latest];\n // @ts-ignore\n sideBarInfo.latest.author = formatAuthor(sideBarInfo.latest.author);\n }\n sideBarInfo = deleteProperties(['readme', '_attachments', '_rev', 'name'], sideBarInfo);\n const authorAvatar = config.web\n ? addGravatarSupport(sideBarInfo, config.web.gravatar)\n : addGravatarSupport(sideBarInfo);\n next(authorAvatar);\n } catch (err) {\n res.status(HTTP_STATUS.NOT_FOUND);\n res.end();\n }\n }\n );\n\n return router;\n}\n\nexport default addSidebarWebApi;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"sidebar.js","names":["_debug","_interopRequireDefault","require","_express","_core","_logger","_middleware","_tarball","_utils","_webUtils","e","__esModule","default","debug","buildDebug","addSidebarWebApi","config","storage","auth","router","Router","can","allow","beforeAll","a","b","logger","trace","afterAll","get","WebUrls","sidebar_scopped_package","sidebar_package","req","res","next","rawScope","params","scope","slice","name","addScope","package","requestOptions","protocol","headers","host","remoteAddress","socket","info","getPackageByOptions","uplinksLook","keepUpLinkData","v","query","sideBarInfo","versions","convertDistRemoteToLocalTarballUrls","hostname","url_prefix","isVersionValid","latest","author","formatAuthor","DIST_TAGS","deleteProperties","authorAvatar","web","addGravatarSupport","gravatar","err","status","HTTP_STATUS","NOT_FOUND","end","_default","exports"],"sources":["../../src/api/sidebar.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Router } from 'express';\n\nimport { Auth } from '@verdaccio/auth';\nimport { DIST_TAGS, HTTP_STATUS } from '@verdaccio/core';\nimport { logger } from '@verdaccio/logger';\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend, allow } from '@verdaccio/middleware';\n// Was required by other packages\nimport { WebUrls } from '@verdaccio/middleware';\nimport { Storage } from '@verdaccio/store';\nimport { convertDistRemoteToLocalTarballUrls } from '@verdaccio/tarball';\nimport { Config, Manifest, Version } from '@verdaccio/types';\nimport { addGravatarSupport, formatAuthor, isVersionValid } from '@verdaccio/utils';\n\nimport { AuthorAvatar, addScope, deleteProperties } from '../web-utils';\n\nexport { $RequestExtend, $ResponseExtend, $NextFunctionVer }; // Was required by other packages\n\nexport type PackageExt = Manifest & { author: AuthorAvatar; dist?: { tarball: string } };\n\nexport type $SidebarPackage = Manifest & { latest: Version };\nconst debug = buildDebug('verdaccio:web:api:sidebar');\n\nfunction addSidebarWebApi(config: Config, storage: Storage, auth: Auth): Router {\n debug('initialized sidebar web api');\n const router = Router(); /* eslint new-cap: 0 */\n const can = allow(auth, {\n beforeAll: (a, b) => logger.trace(a, b),\n afterAll: (a, b) => logger.trace(a, b),\n });\n // Get package sidebar\n router.get(\n [WebUrls.sidebar_scopped_package, WebUrls.sidebar_package],\n can('access'),\n async function (\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n ): Promise<void> {\n const rawScope = req.params.scope; // May include '@'\n const scope = rawScope ? rawScope.slice(1) : null; // Remove '@' if present\n const name: string = scope ? addScope(scope, req.params.package) : req.params.package;\n const requestOptions = {\n protocol: req.protocol,\n headers: req.headers as any,\n // FIXME: if we migrate to req.hostname, the port is not longer included.\n host: req.host,\n remoteAddress: req.socket.remoteAddress,\n };\n try {\n const info = (await storage.getPackageByOptions({\n name,\n uplinksLook: true,\n keepUpLinkData: true,\n requestOptions,\n })) as Manifest;\n const { v } = req.query;\n let sideBarInfo = { ...info };\n sideBarInfo.versions = convertDistRemoteToLocalTarballUrls(\n info,\n { protocol: req.protocol, headers: req.headers as any, host: req.hostname },\n config.url_prefix\n ).versions;\n // TODO: review this implementation\n if (typeof v === 'string' && isVersionValid(info, v)) {\n // @ts-ignore\n sideBarInfo.latest = sideBarInfo.versions[v];\n // @ts-ignore\n sideBarInfo.latest.author = formatAuthor(sideBarInfo.latest.author);\n } else {\n // @ts-ignore\n sideBarInfo.latest = sideBarInfo.versions[info[DIST_TAGS].latest];\n // @ts-ignore\n sideBarInfo.latest.author = formatAuthor(sideBarInfo.latest.author);\n }\n sideBarInfo = deleteProperties(['readme', '_attachments', '_rev', 'name'], sideBarInfo);\n const authorAvatar = config.web\n ? addGravatarSupport(sideBarInfo, config.web.gravatar)\n : addGravatarSupport(sideBarInfo);\n next(authorAvatar);\n } catch (err) {\n res.status(HTTP_STATUS.NOT_FOUND);\n res.end();\n }\n }\n );\n\n return router;\n}\n\nexport default addSidebarWebApi;\n"],"mappings":"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","ignoreList":[]}
package/build/api/user.js CHANGED
@@ -13,7 +13,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
13
13
  const debug = (0, _debug.default)('verdaccio:web:api:user');
14
14
  function addUserAuthApi(auth, config) {
15
15
  const route = (0, _express.Router)(); /* eslint new-cap: 0 */
16
- route.post('/login', (0, _middleware.rateLimit)(config?.userRateLimit), function (req, res, next) {
16
+ route.post(_middleware.WebUrls.user_login, (0, _middleware.rateLimit)(config?.userRateLimit), function (req, res, next) {
17
17
  const {
18
18
  username,
19
19
  password
@@ -36,7 +36,7 @@ function addUserAuthApi(auth, config) {
36
36
  });
37
37
  });
38
38
  if (config?.flags?.changePassword === true) {
39
- route.put('/reset_password', (0, _middleware.rateLimit)(config?.userRateLimit), function (req, res, next) {
39
+ route.put(_middleware.WebUrls.reset_password, (0, _middleware.rateLimit)(config?.userRateLimit), function (req, res, next) {
40
40
  if (_lodash.default.isNil(req.remote_user.name)) {
41
41
  res.status(_core.HTTP_STATUS.UNAUTHORIZED);
42
42
  return next({
@@ -1 +1 @@
1
- {"version":3,"file":"user.js","names":["_debug","_interopRequireDefault","require","_express","_lodash","_core","_middleware","e","__esModule","default","debug","buildDebug","addUserAuthApi","auth","config","route","Router","post","rateLimit","userRateLimit","req","res","next","username","password","body","authenticate","err","user","errorCode","message","HTTP_STATUS","UNAUTHORIZED","INTERNAL_ERROR","errorUtils","getCode","remote_user","jWTSignOptions","security","web","sign","set","HEADERS","CACHE_CONTROL","token","jwtEncrypt","name","flags","changePassword","put","_","isNil","status","API_ERROR","MUST_BE_LOGGED","validatioUtils","validatePassword","new","serverSettings","passwordValidationRegex","BAD_REQUEST","APP_ERROR","PASSWORD_VALIDATION","old","isUpdated","ok","getInternalError","INTERNAL_SERVER_ERROR","_default","exports"],"sources":["../../src/api/user.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Request, Response, Router } from 'express';\nimport _ from 'lodash';\n\nimport { Auth } from '@verdaccio/auth';\nimport {\n API_ERROR,\n APP_ERROR,\n HEADERS,\n HTTP_STATUS,\n VerdaccioError,\n errorUtils,\n validatioUtils,\n} from '@verdaccio/core';\nimport { rateLimit } from '@verdaccio/middleware';\nimport { Config, JWTSignOptions, RemoteUser } from '@verdaccio/types';\n\nimport { $NextFunctionVer } from './package';\n\nconst debug = buildDebug('verdaccio:web:api:user');\n\nfunction addUserAuthApi(auth: Auth, config: Config): Router {\n const route = Router(); /* eslint new-cap: 0 */\n route.post(\n '/login',\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n const { username, password } = req.body;\n debug('authenticate %o', username);\n auth.authenticate(\n username,\n password,\n async (err: VerdaccioError | null, user?: RemoteUser): Promise<void> => {\n if (err) {\n const errorCode = err.message ? HTTP_STATUS.UNAUTHORIZED : HTTP_STATUS.INTERNAL_ERROR;\n debug('error authenticate %o', errorCode);\n next(errorUtils.getCode(errorCode, err.message));\n } else {\n req.remote_user = user as RemoteUser;\n const jWTSignOptions: JWTSignOptions = config.security.web.sign;\n res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');\n next({\n token: await auth.jwtEncrypt(user as RemoteUser, jWTSignOptions),\n username: req.remote_user.name,\n });\n }\n }\n );\n }\n );\n\n if (config?.flags?.changePassword === true) {\n route.put(\n '/reset_password',\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n if (_.isNil(req.remote_user.name)) {\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n // FUTURE: update to a more meaningful message\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n\n const { password } = req.body;\n const { name } = req.remote_user;\n\n if (\n validatioUtils.validatePassword(\n password.new,\n config?.serverSettings?.passwordValidationRegex\n ) === false\n ) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, APP_ERROR.PASSWORD_VALIDATION));\n }\n\n auth.changePassword(name as string, password.old, password.new, (err, isUpdated): void => {\n if (_.isNil(err) && isUpdated) {\n next({\n ok: true,\n });\n } else {\n return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));\n }\n });\n }\n );\n }\n\n return route;\n}\n\nexport default addUserAuthApi;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"user.js","names":["_debug","_interopRequireDefault","require","_express","_lodash","_core","_middleware","e","__esModule","default","debug","buildDebug","addUserAuthApi","auth","config","route","Router","post","WebUrls","user_login","rateLimit","userRateLimit","req","res","next","username","password","body","authenticate","err","user","errorCode","message","HTTP_STATUS","UNAUTHORIZED","INTERNAL_ERROR","errorUtils","getCode","remote_user","jWTSignOptions","security","web","sign","set","HEADERS","CACHE_CONTROL","token","jwtEncrypt","name","flags","changePassword","put","reset_password","_","isNil","status","API_ERROR","MUST_BE_LOGGED","validatioUtils","validatePassword","new","serverSettings","passwordValidationRegex","BAD_REQUEST","APP_ERROR","PASSWORD_VALIDATION","old","isUpdated","ok","getInternalError","INTERNAL_SERVER_ERROR","_default","exports"],"sources":["../../src/api/user.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Request, Response, Router } from 'express';\nimport _ from 'lodash';\n\nimport { Auth } from '@verdaccio/auth';\nimport {\n API_ERROR,\n APP_ERROR,\n HEADERS,\n HTTP_STATUS,\n VerdaccioError,\n errorUtils,\n validatioUtils,\n} from '@verdaccio/core';\nimport { rateLimit } from '@verdaccio/middleware';\nimport { WebUrls } from '@verdaccio/middleware';\nimport { Config, JWTSignOptions, RemoteUser } from '@verdaccio/types';\n\nimport { $NextFunctionVer } from './package';\n\nconst debug = buildDebug('verdaccio:web:api:user');\n\nfunction addUserAuthApi(auth: Auth, config: Config): Router {\n const route = Router(); /* eslint new-cap: 0 */\n route.post(\n WebUrls.user_login,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n const { username, password } = req.body;\n debug('authenticate %o', username);\n auth.authenticate(\n username,\n password,\n async (err: VerdaccioError | null, user?: RemoteUser): Promise<void> => {\n if (err) {\n const errorCode = err.message ? HTTP_STATUS.UNAUTHORIZED : HTTP_STATUS.INTERNAL_ERROR;\n debug('error authenticate %o', errorCode);\n next(errorUtils.getCode(errorCode, err.message));\n } else {\n req.remote_user = user as RemoteUser;\n const jWTSignOptions: JWTSignOptions = config.security.web.sign;\n res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');\n next({\n token: await auth.jwtEncrypt(user as RemoteUser, jWTSignOptions),\n username: req.remote_user.name,\n });\n }\n }\n );\n }\n );\n\n if (config?.flags?.changePassword === true) {\n route.put(\n WebUrls.reset_password,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n if (_.isNil(req.remote_user.name)) {\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n // FUTURE: update to a more meaningful message\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n\n const { password } = req.body;\n const { name } = req.remote_user;\n\n if (\n validatioUtils.validatePassword(\n password.new,\n config?.serverSettings?.passwordValidationRegex\n ) === false\n ) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, APP_ERROR.PASSWORD_VALIDATION));\n }\n\n auth.changePassword(name as string, password.old, password.new, (err, isUpdated): void => {\n if (_.isNil(err) && isUpdated) {\n next({\n ok: true,\n });\n } else {\n return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));\n }\n });\n }\n );\n }\n\n return route;\n}\n\nexport default addUserAuthApi;\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdaccio/web",
3
- "version": "8.1.0-next-8.6",
3
+ "version": "8.1.0-next-8.8",
4
4
  "description": "web ui middleware",
5
5
  "main": "./build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -24,30 +24,29 @@
24
24
  },
25
25
  "license": "MIT",
26
26
  "dependencies": {
27
- "@verdaccio/auth": "8.0.0-next-8.6",
28
- "@verdaccio/config": "8.0.0-next-8.6",
29
- "@verdaccio/core": "8.0.0-next-8.6",
27
+ "@verdaccio/auth": "8.0.0-next-8.8",
28
+ "@verdaccio/config": "8.0.0-next-8.8",
29
+ "@verdaccio/core": "8.0.0-next-8.8",
30
30
  "@verdaccio/loaders": "8.0.0-next-8.4",
31
- "@verdaccio/logger": "8.0.0-next-8.6",
32
- "@verdaccio/middleware": "8.0.0-next-8.6",
33
- "@verdaccio/store": "8.0.0-next-8.6",
34
- "@verdaccio/tarball": "13.0.0-next-8.6",
35
- "@verdaccio/url": "13.0.0-next-8.6",
36
- "@verdaccio/utils": "8.1.0-next-8.6",
37
- "debug": "4.3.7",
31
+ "@verdaccio/logger": "8.0.0-next-8.8",
32
+ "@verdaccio/middleware": "8.0.0-next-8.8",
33
+ "@verdaccio/store": "8.0.0-next-8.8",
34
+ "@verdaccio/tarball": "13.0.0-next-8.8",
35
+ "@verdaccio/url": "13.0.0-next-8.8",
36
+ "@verdaccio/utils": "8.1.0-next-8.8",
37
+ "debug": "4.4.0",
38
38
  "express": "4.21.2",
39
39
  "lodash": "4.17.21"
40
40
  },
41
41
  "devDependencies": {
42
- "@verdaccio/api": "8.1.0-next-8.6",
43
- "@verdaccio/test-helper": "4.0.0-next-8.2",
44
- "@verdaccio/types": "13.0.0-next-8.2",
45
- "jsdom": "20.0.3",
46
- "nock": "13.5.1",
42
+ "@verdaccio/api": "8.1.0-next-8.8",
43
+ "@verdaccio/test-helper": "4.0.0-next-8.3",
44
+ "@verdaccio/types": "13.0.0-next-8.3",
45
+ "jsdom": "25.0.1",
47
46
  "node-html-parser": "4.1.5",
48
47
  "supertest": "7.0.0",
49
- "verdaccio-auth-memory": "13.0.0-next-8.6",
50
- "verdaccio-memory": "13.0.0-next-8.6"
48
+ "verdaccio-auth-memory": "13.0.0-next-8.8",
49
+ "verdaccio-memory": "13.0.0-next-8.8"
51
50
  },
52
51
  "funding": {
53
52
  "type": "opencollective",
@@ -5,6 +5,7 @@ import _ from 'lodash';
5
5
  import { Auth } from '@verdaccio/auth';
6
6
  import { logger } from '@verdaccio/logger';
7
7
  import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '@verdaccio/middleware';
8
+ import { WebUrls } from '@verdaccio/middleware';
8
9
  import { Storage } from '@verdaccio/store';
9
10
  import { getLocalRegistryTarballUri } from '@verdaccio/tarball';
10
11
  import { Config, RemoteUser, Version } from '@verdaccio/types';
@@ -88,7 +89,7 @@ function addPackageWebApi(storage: Storage, auth: Auth, config: Config): Router
88
89
 
89
90
  // Get list of all visible package
90
91
  pkgRouter.get(
91
- '/packages',
92
+ WebUrls.packages_all,
92
93
  async function (
93
94
  req: $RequestExtend,
94
95
  res: $ResponseExtend,
package/src/api/readme.ts CHANGED
@@ -2,11 +2,14 @@ import buildDebug from 'debug';
2
2
  import { Router } from 'express';
3
3
 
4
4
  import { Auth } from '@verdaccio/auth';
5
- import { HEADERS, HEADER_TYPE } from '@verdaccio/core';
5
+ import { DIST_TAGS, HEADERS, HEADER_TYPE } from '@verdaccio/core';
6
6
  import { logger } from '@verdaccio/logger';
7
7
  import { $NextFunctionVer, $RequestExtend, $ResponseExtend, allow } from '@verdaccio/middleware';
8
+ // Was required by other packages
9
+ import { WebUrls } from '@verdaccio/middleware';
8
10
  import { Storage } from '@verdaccio/store';
9
11
  import { Manifest } from '@verdaccio/types';
12
+ import { isVersionValid } from '@verdaccio/utils';
10
13
 
11
14
  import { AuthorAvatar, addScope } from '../web-utils';
12
15
 
@@ -16,6 +19,7 @@ export { $RequestExtend, $ResponseExtend, $NextFunctionVer }; // Was required by
16
19
  export type PackageExt = Manifest & { author: AuthorAvatar; dist?: { tarball: string } };
17
20
  export const NOT_README_FOUND = 'ERROR: No README data found!';
18
21
  const debug = buildDebug('verdaccio:web:api:readme');
22
+
19
23
  const getReadme = (readme) => {
20
24
  if (typeof readme === 'string' && readme.length === 0) {
21
25
  return NOT_README_FOUND;
@@ -27,6 +31,25 @@ const getReadme = (readme) => {
27
31
  }
28
32
  };
29
33
 
34
+ const getReadmeFromManifest = (manifest: Manifest, v?: any): string | undefined => {
35
+ let id;
36
+ let readme;
37
+ if (typeof v === 'string' && isVersionValid(manifest, v)) {
38
+ id = 'version';
39
+ readme = manifest.versions[v].readme;
40
+ }
41
+ if (!readme && isVersionValid(manifest, manifest[DIST_TAGS]?.latest)) {
42
+ id = 'latest';
43
+ readme = manifest.versions[manifest[DIST_TAGS].latest].readme;
44
+ }
45
+ if (!readme && manifest.readme) {
46
+ id = 'root';
47
+ readme = manifest.readme;
48
+ }
49
+ debug('readme: %o %o', v, id);
50
+ return readme;
51
+ };
52
+
30
53
  function addReadmeWebApi(storage: Storage, auth: Auth): Router {
31
54
  debug('initialized readme web api');
32
55
  const can = allow(auth, {
@@ -36,7 +59,7 @@ function addReadmeWebApi(storage: Storage, auth: Auth): Router {
36
59
  const pkgRouter = Router(); /* eslint new-cap: 0 */
37
60
 
38
61
  pkgRouter.get(
39
- '/package/readme/:scope(@[^/]+)?/:package/:version?',
62
+ [WebUrls.readme_package_scoped_version, WebUrls.readme_package_version],
40
63
  can('access'),
41
64
  async function (
42
65
  req: $RequestExtend,
@@ -64,7 +87,9 @@ function addReadmeWebApi(storage: Storage, auth: Auth): Router {
64
87
  })) as Manifest;
65
88
  debug('readme pkg %o', manifest?.name);
66
89
  res.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_PLAIN_UTF8);
67
- next(getReadme(manifest.readme));
90
+ const { v } = req.query;
91
+ const readme = getReadmeFromManifest(manifest, v);
92
+ next(getReadme(readme));
68
93
  } catch (err) {
69
94
  next(err);
70
95
  }
package/src/api/search.ts CHANGED
@@ -6,6 +6,7 @@ import { URLSearchParams } from 'url';
6
6
  import { Auth } from '@verdaccio/auth';
7
7
  import { errorUtils, searchUtils } from '@verdaccio/core';
8
8
  import { SearchQuery } from '@verdaccio/core/src/search-utils';
9
+ import { WebUrls } from '@verdaccio/middleware';
9
10
  import { Storage } from '@verdaccio/store';
10
11
  import { Manifest } from '@verdaccio/types';
11
12
 
@@ -35,7 +36,7 @@ function checkAccess(pkg: any, auth: any, remoteUser): Promise<Manifest | null>
35
36
  function addSearchWebApi(storage: Storage, auth: Auth): Router {
36
37
  const router = Router(); /* eslint new-cap: 0 */
37
38
  router.get(
38
- '/search/:anything',
39
+ WebUrls.search,
39
40
  async function (
40
41
  req: $RequestExtend,
41
42
  res: $ResponseExtend,
@@ -5,6 +5,8 @@ import { Auth } from '@verdaccio/auth';
5
5
  import { DIST_TAGS, HTTP_STATUS } from '@verdaccio/core';
6
6
  import { logger } from '@verdaccio/logger';
7
7
  import { $NextFunctionVer, $RequestExtend, $ResponseExtend, allow } from '@verdaccio/middleware';
8
+ // Was required by other packages
9
+ import { WebUrls } from '@verdaccio/middleware';
8
10
  import { Storage } from '@verdaccio/store';
9
11
  import { convertDistRemoteToLocalTarballUrls } from '@verdaccio/tarball';
10
12
  import { Config, Manifest, Version } from '@verdaccio/types';
@@ -28,7 +30,7 @@ function addSidebarWebApi(config: Config, storage: Storage, auth: Auth): Router
28
30
  });
29
31
  // Get package sidebar
30
32
  router.get(
31
- '/sidebar/:scope(@[^/]+)?/:package',
33
+ [WebUrls.sidebar_scopped_package, WebUrls.sidebar_package],
32
34
  can('access'),
33
35
  async function (
34
36
  req: $RequestExtend,
package/src/api/user.ts CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  validatioUtils,
14
14
  } from '@verdaccio/core';
15
15
  import { rateLimit } from '@verdaccio/middleware';
16
+ import { WebUrls } from '@verdaccio/middleware';
16
17
  import { Config, JWTSignOptions, RemoteUser } from '@verdaccio/types';
17
18
 
18
19
  import { $NextFunctionVer } from './package';
@@ -22,7 +23,7 @@ const debug = buildDebug('verdaccio:web:api:user');
22
23
  function addUserAuthApi(auth: Auth, config: Config): Router {
23
24
  const route = Router(); /* eslint new-cap: 0 */
24
25
  route.post(
25
- '/login',
26
+ WebUrls.user_login,
26
27
  rateLimit(config?.userRateLimit),
27
28
  function (req: Request, res: Response, next: $NextFunctionVer): void {
28
29
  const { username, password } = req.body;
@@ -51,7 +52,7 @@ function addUserAuthApi(auth: Auth, config: Config): Router {
51
52
 
52
53
  if (config?.flags?.changePassword === true) {
53
54
  route.put(
54
- '/reset_password',
55
+ WebUrls.reset_password,
55
56
  rateLimit(config?.userRateLimit),
56
57
  function (req: Request, res: Response, next: $NextFunctionVer): void {
57
58
  if (_.isNil(req.remote_user.name)) {
@@ -73,4 +73,33 @@ describe('readme api', () => {
73
73
  .expect(HTTP_STATUS.OK);
74
74
  expect(response.text).toMatch(NOT_README_FOUND);
75
75
  });
76
+
77
+ test('should fetch readme with keeping all readmes (latest)', async () => {
78
+ const app = await initializeServer('keep-all-readmes.yaml');
79
+ await publishVersion(app, 'pk1-test', '1.0.0', { readme: 'my readme' });
80
+ const response = await supertest(app)
81
+ .get('/-/verdaccio/data/package/readme/pk1-test')
82
+ .set('Accept', HEADERS.TEXT_PLAIN)
83
+ .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_PLAIN_UTF8)
84
+ .expect(HTTP_STATUS.OK);
85
+ expect(response.text).toMatch('my readme');
86
+ });
87
+
88
+ test('should fetch readme with keeping all readmes (version)', async () => {
89
+ const app = await initializeServer('keep-all-readmes.yaml');
90
+ await publishVersion(app, 'pk1-test', '1.0.0', { readme: 'my readme' });
91
+ await publishVersion(app, 'pk1-test', '1.2.0', { readme: 'my new readme' });
92
+ const response = await supertest(app)
93
+ .get('/-/verdaccio/data/package/readme/pk1-test')
94
+ .set('Accept', HEADERS.TEXT_PLAIN)
95
+ .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_PLAIN_UTF8)
96
+ .expect(HTTP_STATUS.OK);
97
+ expect(response.text).toMatch('my new readme');
98
+ const response2 = await supertest(app)
99
+ .get('/-/verdaccio/data/package/readme/pk1-test?v=1.0.0')
100
+ .set('Accept', HEADERS.TEXT_PLAIN)
101
+ .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_PLAIN_UTF8)
102
+ .expect(HTTP_STATUS.OK);
103
+ expect(response2.text).toMatch('my readme');
104
+ });
76
105
  });
@@ -0,0 +1,29 @@
1
+ auth:
2
+ auth-memory:
3
+ users:
4
+ test:
5
+ name: test
6
+ password: test
7
+
8
+ web:
9
+ title: verdaccio
10
+
11
+ publish:
12
+ allow_offline: false
13
+ keep_readmes: all
14
+
15
+ uplinks:
16
+
17
+ log: { type: stdout, format: pretty, level: trace }
18
+
19
+ packages:
20
+ '@*/*':
21
+ access: $anonymous
22
+ publish: $anonymous
23
+ '**':
24
+ access: $anonymous
25
+ publish: $anonymous
26
+ _debug: true
27
+
28
+ flags:
29
+ changePassword: true