0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-12-30 22:34:10 -05:00

fix #4984 crashes with path-to-regexp v0.1.12 (#5011)

* fix: express dependencies

* reuse endpoints

* reuse endpoints

* web urls reused

* fix test

* Create smooth-games-share.md
This commit is contained in:
Juan Picado 2024-12-20 09:52:34 +01:00 committed by GitHub
parent f26fb5187a
commit 139861eb08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 145 additions and 96 deletions

View file

@ -0,0 +1,11 @@
---
'@verdaccio/server': patch
'verdaccio-audit': patch
'@verdaccio/test-helper': patch
'@verdaccio/middleware': patch
'@verdaccio/auth': patch
'@verdaccio/api': patch
'@verdaccio/web': patch
---
fix: crashes with path-to-regexp v0.1.12 express

View file

@ -3,9 +3,9 @@ name: E2E Generator Verdaccio Plugin
on:
pull_request:
workflow_dispatch:
push:
branches:
- 'master'
# push:
# branches:
# - 'master'
concurrency:
group: generator-plugin-${{ github.ref }}

View file

@ -5,6 +5,7 @@ import mime from 'mime';
import { Auth } from '@verdaccio/auth';
import { constants, errorUtils } from '@verdaccio/core';
import { allow, media } from '@verdaccio/middleware';
import { DIST_TAGS_API_ENDPOINTS } from '@verdaccio/middleware';
import { Storage } from '@verdaccio/store';
import { Logger } from '@verdaccio/types';
@ -39,21 +40,21 @@ export default function (route: Router, auth: Auth, storage: Storage, logger: Lo
// tagging a package.
route.put(
'/:package/:tag',
DIST_TAGS_API_ENDPOINTS.tagging,
can('publish'),
media(mime.getType('json')),
addTagPackageVersionMiddleware
);
route.put(
'/-/package/:package/dist-tags/:tag',
DIST_TAGS_API_ENDPOINTS.tagging_package,
can('publish'),
media(mime.getType('json')),
addTagPackageVersionMiddleware
);
route.delete(
'/-/package/:package/dist-tags/:tag',
DIST_TAGS_API_ENDPOINTS.tagging_package,
can('publish'),
async function (
req: $RequestExtend,
@ -75,7 +76,7 @@ export default function (route: Router, auth: Auth, storage: Storage, logger: Lo
);
route.get(
'/-/package/:package/dist-tags',
DIST_TAGS_API_ENDPOINTS.get_dist_tags,
can('access'),
async function (
req: $RequestExtend,

View file

@ -4,6 +4,7 @@ import { Router } from 'express';
import { Auth } from '@verdaccio/auth';
import { HEADERS, HEADER_TYPE, stringUtils } from '@verdaccio/core';
import { allow } from '@verdaccio/middleware';
import { PACKAGE_API_ENDPOINTS } from '@verdaccio/middleware';
import { Storage } from '@verdaccio/store';
import { Logger } from '@verdaccio/types';
@ -17,7 +18,7 @@ export default function (route: Router, auth: Auth, storage: Storage, logger: Lo
afterAll: (a, b) => logger.trace(a, b),
});
route.get(
'/:package/:version?',
PACKAGE_API_ENDPOINTS.get_package_by_version,
can('access'),
async function (
req: $RequestExtend,
@ -76,7 +77,7 @@ export default function (route: Router, auth: Auth, storage: Storage, logger: Lo
);
route.get(
'/:package/-/:filename',
PACKAGE_API_ENDPOINTS.get_package_tarball,
can('access'),
async function (req: $RequestExtend, res: $ResponseExtend, next): Promise<void> {
const { package: pkgName, filename } = req.params;

View file

@ -1,10 +1,12 @@
import { Router } from 'express';
import { PING_API_ENDPOINTS } from '@verdaccio/middleware';
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';
export default function (route: Router): void {
route.get(
'/-/ping',
PING_API_ENDPOINTS.ping,
function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
next({});
}

View file

@ -5,13 +5,13 @@ import mime from 'mime';
import { Auth } from '@verdaccio/auth';
import { API_MESSAGE, HTTP_STATUS } from '@verdaccio/core';
import { allow, expectJson, media } from '@verdaccio/middleware';
// import star from './star';
import { PUBLISH_API_ENDPOINTS } from '@verdaccio/middleware';
import { Storage } from '@verdaccio/store';
import { Logger } from '@verdaccio/types';
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';
// import star from './star';
const debug = buildDebug('verdaccio:api:publish');
/**
@ -120,7 +120,7 @@ export default function publish(
afterAll: (a, b) => logger.trace(a, b),
});
router.put(
'/:package',
PUBLISH_API_ENDPOINTS.add_package,
can('publish'),
media(mime.getType('json')),
expectJson,
@ -128,7 +128,7 @@ export default function publish(
);
router.put(
'/:package/-rev/:revision',
PUBLISH_API_ENDPOINTS.publish_package,
can('unpublish'),
media(mime.getType('json')),
expectJson,
@ -143,7 +143,7 @@ export default function publish(
* - no version is specified in the unpublish call
* - all versions are removed npm unpublish package@*
* - there is no versions on the metadata
* then the client decides to DELETE the resource
* Example:
* Get fresh manifest (write=true is a flag to get the latest revision)
@ -153,7 +153,7 @@ export default function publish(
* npm http fetch DELETE 201 http://localhost:4873/package-name/-rev/18-d8ebe3020bd4ac9c 22ms
*/
router.delete(
'/:package/-rev/:revision',
PUBLISH_API_ENDPOINTS.publish_package,
can('unpublish'),
async function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
const packageName = req.params.package;
@ -177,7 +177,7 @@ export default function publish(
npm http fetch DELETE 201 http://localhost:4873/package-name/-rev/18-d8ebe3020bd4ac9c 22ms
*/
router.delete(
'/:package/-/:filename/-rev/:revision',
PUBLISH_API_ENDPOINTS.remove_tarball,
can('unpublish'),
can('publish'),
async function (

View file

@ -1,9 +1,10 @@
import { HTTP_STATUS } from '@verdaccio/core';
import { SEARCH_API_ENDPOINTS } from '@verdaccio/middleware';
import { Logger } from '@verdaccio/types';
export default function (route, logger: Logger): void {
// TODO: next major version, remove this
route.get('/-/all(/since)?', function (_req, res) {
route.get(SEARCH_API_ENDPOINTS.deprecated_search, function (_req, res) {
logger.warn('search endpoint has been removed, please use search v1');
res.status(HTTP_STATUS.NOT_FOUND);
res.json({ error: 'not found, endpoint was removed' });

View file

@ -2,6 +2,7 @@ import { Response, Router } from 'express';
import _ from 'lodash';
import { HTTP_STATUS, USERS, errorUtils } from '@verdaccio/core';
import { STARS_API_ENDPOINTS } from '@verdaccio/middleware';
import { Storage } from '@verdaccio/store';
import { Version } from '@verdaccio/types';
@ -9,7 +10,7 @@ import { $NextFunctionVer, $RequestExtend } from '../types/custom';
export default function (route: Router, storage: Storage): void {
route.get(
'/-/_view/starredByUser',
STARS_API_ENDPOINTS.get_user_starred_packages,
async (req: $RequestExtend, res: Response, next: $NextFunctionVer): Promise<void> => {
const query: { key: string } = req.query;
if (typeof query?.key !== 'string') {

View file

@ -10,6 +10,7 @@ import {
errorUtils,
validatioUtils,
} from '@verdaccio/core';
import { PROFILE_API_ENDPOINTS } from '@verdaccio/middleware';
import { rateLimit } from '@verdaccio/middleware';
import { Config } from '@verdaccio/types';
@ -41,7 +42,7 @@ export default function (route: Router, auth: Auth, config: Config): void {
}
route.get(
'/-/npm/v1/user',
PROFILE_API_ENDPOINTS.get_profile,
rateLimit(config?.userRateLimit),
function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
if (_.isNil(req.remote_user.name) === false) {
@ -56,7 +57,7 @@ export default function (route: Router, auth: Auth, config: Config): void {
);
route.post(
'/-/npm/v1/user',
PROFILE_API_ENDPOINTS.get_profile,
rateLimit(config?.userRateLimit),
function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
if (_.isNil(req.remote_user.name)) {

View file

@ -3,6 +3,7 @@ import _ from 'lodash';
import { Auth } from '@verdaccio/auth';
import { HTTP_STATUS, searchUtils } from '@verdaccio/core';
import { SEARCH_API_ENDPOINTS } from '@verdaccio/middleware';
import { Storage } from '@verdaccio/store';
import { Manifest } from '@verdaccio/types';
import { Logger } from '@verdaccio/types';
@ -35,7 +36,7 @@ export default function (route, auth: Auth, storage: Storage, logger: Logger): v
});
}
route.get('/-/v1/search', async (req, res, next) => {
route.get(SEARCH_API_ENDPOINTS.search, async (req, res, next) => {
const { query, url } = req;
let [size, from] = ['size', 'from'].map((k) => query[k]);
let data;

View file

@ -5,6 +5,7 @@ import { getApiToken } from '@verdaccio/auth';
import { Auth } from '@verdaccio/auth';
import { HEADERS, HTTP_STATUS, SUPPORT_ERRORS, errorUtils } from '@verdaccio/core';
import { rateLimit } from '@verdaccio/middleware';
import { TOKEN_API_ENDPOINTS } from '@verdaccio/middleware';
import { Storage } from '@verdaccio/store';
import { Config, RemoteUser, Token } from '@verdaccio/types';
import { Logger } from '@verdaccio/types';
@ -32,7 +33,7 @@ export default function (
logger: Logger
): void {
route.get(
'/-/npm/v1/tokens',
TOKEN_API_ENDPOINTS.get_tokens,
rateLimit(config?.userRateLimit),
async function (req: $RequestExtend, res: Response, next: $NextFunctionVer) {
const { name } = req.remote_user;
@ -60,7 +61,7 @@ export default function (
);
route.post(
'/-/npm/v1/tokens',
TOKEN_API_ENDPOINTS.get_tokens,
rateLimit(config?.userRateLimit),
function (req: $RequestExtend, res: Response, next: $NextFunctionVer) {
const { password, readonly, cidr_whitelist } = req.body;
@ -131,7 +132,7 @@ export default function (
);
route.delete(
'/-/npm/v1/tokens/token/:tokenKey',
TOKEN_API_ENDPOINTS.delete_token,
rateLimit(config?.userRateLimit),
async (req: $RequestExtend, res: Response, next: $NextFunctionVer) => {
const {

View file

@ -2,21 +2,25 @@ import buildDebug from 'debug';
import { Response, Router } from 'express';
import { errorUtils } from '@verdaccio/core';
import { USER_API_ENDPOINTS } from '@verdaccio/middleware';
import { $NextFunctionVer, $RequestExtend } from '../types/custom';
const debug = buildDebug('verdaccio:api:user');
export default function (route: Router): void {
route.get('/-/whoami', (req: $RequestExtend, _res: Response, next: $NextFunctionVer): any => {
// remote_user is set by the auth middleware
const username = req?.remote_user?.name;
if (!username) {
debug('whoami: user not found');
return next(errorUtils.getUnauthorized('Unauthorized'));
}
route.get(
USER_API_ENDPOINTS.whoami,
(req: $RequestExtend, _res: Response, next: $NextFunctionVer): any => {
// remote_user is set by the auth middleware
const username = req?.remote_user?.name;
if (!username) {
debug('whoami: user not found');
return next(errorUtils.getUnauthorized('Unauthorized'));
}
debug('whoami: response %o', username);
return next({ username: username });
});
debug('whoami: response %o', username);
return next({ username: username });
}
);
}

View file

@ -51,7 +51,7 @@
"@verdaccio/middleware": "workspace:8.0.0-next-8.6",
"@verdaccio/types": "workspace:13.0.0-next-8.2",
"@verdaccio/logger": "workspace:8.0.0-next-8.6",
"express": "4.21.1",
"express": "4.21.2",
"supertest": "7.0.0"
},
"funding": {

View file

@ -43,7 +43,7 @@
"@verdaccio/url": "workspace:13.0.0-next-8.6",
"@verdaccio/utils": "workspace:8.1.0-next-8.6",
"debug": "4.4.0",
"express": "4.21.1",
"express": "4.21.2",
"express-rate-limit": "5.5.1",
"lodash": "4.17.21",
"lru-cache": "7.18.3",

View file

@ -19,3 +19,5 @@ export {
LOG_VERDACCIO_ERROR,
} from './middlewares/log';
export * from './types';
export * from './middlewares/api_urls';
export * from './middlewares/web/web-urls';

View file

@ -0,0 +1,45 @@
export enum USER_API_ENDPOINTS {
whoami = '/-/whoami',
get_user = '/-/user/:org_couchdb_user',
add_user = '/-/user/:org_couchdb_user/:_rev?/:revision?',
user_token = '/-/user/token/*',
}
export enum STARS_API_ENDPOINTS {
get_user_starred_packages = '/-/_view/starredByUser',
}
export enum SEARCH_API_ENDPOINTS {
search = '/-/v1/search',
deprecated_search = '/-/all(/since)?',
}
export enum PUBLISH_API_ENDPOINTS {
add_package = '/:package',
publish_package = '/:package/-rev/:revision',
remove_tarball = '/:package/-/:filename/-rev/:revision',
}
export enum PING_API_ENDPOINTS {
ping = '/-/ping',
}
export enum PACKAGE_API_ENDPOINTS {
get_package_by_version = '/:package/:version?',
get_package_tarball = '/:package/-/:filename',
}
export enum DIST_TAGS_API_ENDPOINTS {
tagging = '/:package/:tag',
tagging_package = '/-/package/:package/dist-tags/:tag',
get_dist_tags = '/-/package/:package/dist-tags',
}
export enum PROFILE_API_ENDPOINTS {
get_profile = '/-/npm/v1/user',
}
export enum TOKEN_API_ENDPOINTS {
get_tokens = '/-/npm/v1/tokens',
delete_token = '/-/npm/v1/tokens/token/:tokenKey',
}

View file

@ -0,0 +1,10 @@
export enum WebUrls {
sidebar_scopped_package = '/sidebar/:scope/:package',
sidebar_package = '/sidebar/:package',
readme_package_scoped_version = '/package/readme/:scope/:package/:version?',
readme_package_version = '/package/readme/:package/:version?',
packages_all = '/packages',
user_login = '/login',
search = '/search/:anything',
reset_password = '/reset_password',
}

View file

@ -32,7 +32,7 @@
"dependencies": {
"@verdaccio/config": "workspace:8.0.0-next-8.6",
"@verdaccio/core": "workspace:8.0.0-next-8.6",
"express": "4.21.1",
"express": "4.21.2",
"https-proxy-agent": "5.0.1",
"node-fetch": "cjs"
},

View file

@ -43,7 +43,7 @@
"compression": "1.7.5",
"cors": "2.8.5",
"debug": "4.4.0",
"express": "4.21.1",
"express": "4.21.2",
"lodash": "4.17.21"
},
"devDependencies": {

View file

@ -19,6 +19,8 @@
"body-parser": "1.20.3",
"debug": "4.4.0",
"express": "4.21.1",
"debug": "4.4.0",
"express": "4.21.2",
"fs-extra": "11.2.0",
"supertest": "7.0.0"
},

View file

@ -5,6 +5,7 @@ import _ from 'lodash';
import { Auth } from '@verdaccio/auth';
import { logger } from '@verdaccio/logger';
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '@verdaccio/middleware';
import { WebUrls } from '@verdaccio/middleware';
import { Storage } from '@verdaccio/store';
import { getLocalRegistryTarballUri } from '@verdaccio/tarball';
import { Config, RemoteUser, Version } from '@verdaccio/types';
@ -88,7 +89,7 @@ function addPackageWebApi(storage: Storage, auth: Auth, config: Config): Router
// Get list of all visible package
pkgRouter.get(
'/packages',
WebUrls.packages_all,
async function (
req: $RequestExtend,
res: $ResponseExtend,

View file

@ -5,6 +5,8 @@ import { Auth } from '@verdaccio/auth';
import { HEADERS, HEADER_TYPE } from '@verdaccio/core';
import { logger } from '@verdaccio/logger';
import { $NextFunctionVer, $RequestExtend, $ResponseExtend, allow } from '@verdaccio/middleware';
// Was required by other packages
import { WebUrls } from '@verdaccio/middleware';
import { Storage } from '@verdaccio/store';
import { Manifest } from '@verdaccio/types';
@ -36,7 +38,7 @@ function addReadmeWebApi(storage: Storage, auth: Auth): Router {
const pkgRouter = Router(); /* eslint new-cap: 0 */
pkgRouter.get(
'/package/readme/:scope(@[^/]+)?/:package/:version?',
[WebUrls.readme_package_scoped_version, WebUrls.readme_package_version],
can('access'),
async function (
req: $RequestExtend,

View file

@ -6,6 +6,7 @@ import { URLSearchParams } from 'url';
import { Auth } from '@verdaccio/auth';
import { errorUtils, searchUtils } from '@verdaccio/core';
import { SearchQuery } from '@verdaccio/core/src/search-utils';
import { WebUrls } from '@verdaccio/middleware';
import { Storage } from '@verdaccio/store';
import { Manifest } from '@verdaccio/types';
@ -35,7 +36,7 @@ function checkAccess(pkg: any, auth: any, remoteUser): Promise<Manifest | null>
function addSearchWebApi(storage: Storage, auth: Auth): Router {
const router = Router(); /* eslint new-cap: 0 */
router.get(
'/search/:anything',
WebUrls.search,
async function (
req: $RequestExtend,
res: $ResponseExtend,

View file

@ -5,6 +5,8 @@ import { Auth } from '@verdaccio/auth';
import { DIST_TAGS, HTTP_STATUS } from '@verdaccio/core';
import { logger } from '@verdaccio/logger';
import { $NextFunctionVer, $RequestExtend, $ResponseExtend, allow } from '@verdaccio/middleware';
// Was required by other packages
import { WebUrls } from '@verdaccio/middleware';
import { Storage } from '@verdaccio/store';
import { convertDistRemoteToLocalTarballUrls } from '@verdaccio/tarball';
import { Config, Manifest, Version } from '@verdaccio/types';
@ -28,7 +30,7 @@ function addSidebarWebApi(config: Config, storage: Storage, auth: Auth): Router
});
// Get package sidebar
router.get(
'/sidebar/:scope(@[^/]+)?/:package',
[WebUrls.sidebar_scopped_package, WebUrls.sidebar_package],
can('access'),
async function (
req: $RequestExtend,

View file

@ -13,6 +13,7 @@ import {
validatioUtils,
} from '@verdaccio/core';
import { rateLimit } from '@verdaccio/middleware';
import { WebUrls } from '@verdaccio/middleware';
import { Config, JWTSignOptions, RemoteUser } from '@verdaccio/types';
import { $NextFunctionVer } from './package';
@ -22,7 +23,7 @@ const debug = buildDebug('verdaccio:web:api:user');
function addUserAuthApi(auth: Auth, config: Config): Router {
const route = Router(); /* eslint new-cap: 0 */
route.post(
'/login',
WebUrls.user_login,
rateLimit(config?.userRateLimit),
function (req: Request, res: Response, next: $NextFunctionVer): void {
const { username, password } = req.body;
@ -51,7 +52,7 @@ function addUserAuthApi(auth: Auth, config: Config): Router {
if (config?.flags?.changePassword === true) {
route.put(
'/reset_password',
WebUrls.reset_password,
rateLimit(config?.userRateLimit),
function (req: Request, res: Response, next: $NextFunctionVer): void {
if (_.isNil(req.remote_user.name)) {

View file

@ -635,8 +635,8 @@ importers:
specifier: workspace:13.0.0-next-8.2
version: link:../core/types
express:
specifier: 4.21.1
version: 4.21.1
specifier: 4.21.2
version: 4.21.2(supports-color@6.1.0)
supertest:
specifier: 7.0.0
version: 7.0.0
@ -940,8 +940,8 @@ importers:
specifier: 4.4.0
version: 4.4.0(supports-color@5.5.0)
express:
specifier: 4.21.1
version: 4.21.1
specifier: 4.21.2
version: 4.21.2(supports-color@6.1.0)
express-rate-limit:
specifier: 5.5.1
version: 5.5.1
@ -1014,8 +1014,8 @@ importers:
specifier: workspace:8.0.0-next-8.6
version: link:../../core/core
express:
specifier: 4.21.1
version: 4.21.1
specifier: 4.21.2
version: 4.21.2(supports-color@6.1.0)
https-proxy-agent:
specifier: 5.0.1
version: 5.0.1
@ -1555,8 +1555,8 @@ importers:
specifier: 4.4.0
version: 4.4.0(supports-color@5.5.0)
express:
specifier: 4.21.1
version: 4.21.1
specifier: 4.21.2
version: 4.21.2(supports-color@6.1.0)
lodash:
specifier: 4.17.21
version: 4.17.21
@ -1852,8 +1852,8 @@ importers:
specifier: 4.4.0
version: 4.4.0(supports-color@5.5.0)
express:
specifier: 4.21.1
version: 4.21.1
specifier: 4.21.2
version: 4.21.2(supports-color@6.1.0)
fs-extra:
specifier: 11.2.0
version: 11.2.0
@ -17547,44 +17547,6 @@ packages:
resolution: {integrity: sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==}
dev: false
/express@4.21.1:
resolution: {integrity: sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==}
engines: {node: '>= 0.10.0'}
dependencies:
accepts: 1.3.8
array-flatten: 1.1.1
body-parser: 1.20.3(supports-color@6.1.0)
content-disposition: 0.5.4
content-type: 1.0.5
cookie: 0.7.1
cookie-signature: 1.0.6
debug: 2.6.9(supports-color@6.1.0)
depd: 2.0.0
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
finalhandler: 1.3.1(supports-color@6.1.0)
fresh: 0.5.2
http-errors: 2.0.0
merge-descriptors: 1.0.3
methods: 1.1.2
on-finished: 2.4.1
parseurl: 1.3.3
path-to-regexp: 0.1.10
proxy-addr: 2.0.7
qs: 6.13.0
range-parser: 1.2.1
safe-buffer: 5.2.1
send: 0.19.0(supports-color@6.1.0)
serve-static: 1.16.2(supports-color@6.1.0)
setprototypeof: 1.2.0
statuses: 2.0.1
type-is: 1.6.18
utils-merge: 1.0.1
vary: 1.1.2
transitivePeerDependencies:
- supports-color
/express@4.21.2(supports-color@6.1.0):
resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==}
engines: {node: '>= 0.10.0'}
@ -24533,9 +24495,6 @@ packages:
lru-cache: 10.4.3
minipass: 7.1.2
/path-to-regexp@0.1.10:
resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==}
/path-to-regexp@0.1.12:
resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==}