Compare commits

...

19 Commits

Author SHA1 Message Date
github-actions[bot]
fa3d878286 chore: update versions (6-next) (#2625)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2021-11-05 17:29:26 +01:00
Diana Morales
20c9e43edc dist-tags endpoint fastify (#2638)
* Create dist-tags.ts

* feat:migrate dist-tags to fastify

* Update storage.ts

Uncomment self.filters code

* add changeset
2021-11-05 16:59:13 +01:00
Diana Morales
18dc5f1f2f feat: migrate web login endpoint to fastify (#2624)
* feat: migrate login to fastify

* Update package.json

* Update server.ts

* fix authentication tests

* fix test
2021-11-05 16:29:48 +01:00
renovate[bot]
b7d319c5be chore(deps): update dependency @types/react to v17.0.34 (#2628)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-11-04 09:38:57 +01:00
Diana Morales
f86c31ed0e feat: migrate sidebar to fastify (#2618) 2021-11-03 20:56:36 +01:00
renovate[bot]
076f0f85e8 fix(deps): update docusaurus monorepo to v2.0.0-beta.9 (#2622)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-11-03 18:25:53 +01:00
Diana Morales
c2a1f4a73a use warning code for deprecation warnings (#2615) 2021-10-31 15:49:06 +01:00
Diana Morales
41475949ba feat: migrate readme to fastify (#2613)
* feat: migrate readme to fastify

* Update readme.ts
2021-10-31 15:00:04 +01:00
renovate[bot]
d390a66158 chore(deps): update dependency @types/validator to v13.6.6 (#2609) 2021-10-30 14:15:58 +02:00
renovate[bot]
7041a4381e chore(deps): update dependency css-loader to v6.5.0 (#2608) 2021-10-30 11:32:31 +02:00
renovate[bot]
14d973c552 chore(deps): update dependency redux to v4.1.2 (#2602) 2021-10-29 18:55:30 +02:00
Behrang Yarahmadi
13310814da #2606 add prettier plugin sort imports (#2607)
* #2606 add prettier plugin sort imprts

* #2606 update pnpm-lock.yaml

* #2606 update eslint rules

* #2606 fixes website directory formatting

Co-authored-by: Ayush Sharma <ayush.sharma@trivago.com>
2021-10-29 17:33:05 +02:00
Juan Picado
16458f801e refactor: pass options instead request object (#2605) 2021-10-29 09:00:02 +02:00
renovate[bot]
1322ffc2c4 chore(deps): update dependency @types/node to v16.11.6 (#2603) 2021-10-29 05:24:10 +02:00
renovate[bot]
2091f268d3 chore(deps): update dependency tmp-promise to v3.0.3 (#2592) 2021-10-28 21:40:22 +02:00
renovate[bot]
28331ff07a chore(deps): update dependency @crowdin/cli to v3.7.1 (#2601)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-28 17:44:57 +02:00
renovate[bot]
1ad1214c5e chore(deps): update dependency @testing-library/dom to v8.10.1 (#2583)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-28 17:12:24 +02:00
Juan Picado
cf4489abb1 feat: download tarball endpoint fastify (#2600) 2021-10-27 23:06:41 +02:00
Diana Morales
d7bf5453b1 feat:migrate whoami to fastify (#2599) 2021-10-27 21:34:30 +02:00
452 changed files with 3156 additions and 2218 deletions

View File

@@ -82,7 +82,9 @@
"shaggy-parrots-smash",
"shiny-chefs-heal",
"smart-apricots-kneel",
"sour-buses-shout",
"spicy-frogs-press",
"ten-parents-breathe",
"tender-bags-call",
"three-pots-sit",
"two-dolls-check",

View File

@@ -0,0 +1,11 @@
---
'@verdaccio/fastify-migration': minor
'@verdaccio/store': minor
'@verdaccio/utils': minor
'@verdaccio/web': minor
'@verdaccio/website': minor
---
feat: migrate web sidebar endpoint to fastify
reuse utils methods between packages

View File

@@ -0,0 +1,7 @@
---
'@verdaccio/auth': minor
'@verdaccio/fastify-migration': minor
'@verdaccio/web': minor
---
dist tags Implementation on Fastify

View File

@@ -1,11 +0,0 @@
{
"endOfLine": "lf",
"useTabs": false,
"printWidth": 100,
"tabWidth": 2,
"singleQuote": true,
"bracketSpacing": true,
"jsxBracketSameLine": true,
"trailingComma": "es5",
"semi": true
}

View File

@@ -41,7 +41,8 @@
"@changesets/changelog-github": "0.2.8",
"@changesets/cli": "2.15.0",
"@changesets/get-dependents-graph": "1.2.2",
"@crowdin/cli": "3.7.0",
"@crowdin/cli": "3.7.1",
"@trivago/prettier-plugin-sort-imports": "3.0.0",
"@types/async": "3.2.7",
"@types/autocannon": "4.1.1",
"@types/autosuggest-highlight": "3.1.1",
@@ -56,7 +57,7 @@
"@types/semver": "7.3.9",
"@types/supertest": "2.0.11",
"@types/testing-library__jest-dom": "5.14.1",
"@types/validator": "13.6.5",
"@types/validator": "13.6.6",
"@types/webpack": "5.28.0",
"@types/webpack-env": "1.16.3",
"@typescript-eslint/eslint-plugin": "4.33.0",

View File

@@ -1,5 +1,19 @@
# @verdaccio/api
## 6.0.0-6-next.18
### Patch Changes
- Updated dependencies [f86c31ed]
- Updated dependencies [20c9e43e]
- @verdaccio/store@6.0.0-6-next.16
- @verdaccio/utils@6.0.0-6-next.9
- @verdaccio/auth@6.0.0-6-next.15
- @verdaccio/config@6.0.0-6-next.11
- @verdaccio/tarball@11.0.0-6-next.10
- @verdaccio/middleware@6.0.0-6-next.15
- @verdaccio/hooks@6.0.0-6-next.9
## 6.0.0-6-next.17
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/api",
"version": "6.0.0-6-next.17",
"version": "6.0.0-6-next.18",
"description": "loaders logic",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -39,15 +39,15 @@
},
"license": "MIT",
"dependencies": {
"@verdaccio/auth": "workspace:6.0.0-6-next.14",
"@verdaccio/config": "workspace:6.0.0-6-next.10",
"@verdaccio/auth": "workspace:6.0.0-6-next.15",
"@verdaccio/config": "workspace:6.0.0-6-next.11",
"@verdaccio/core": "workspace:6.0.0-6-next.3",
"@verdaccio/hooks": "workspace:6.0.0-6-next.9",
"@verdaccio/logger": "workspace:6.0.0-6-next.7",
"@verdaccio/middleware": "workspace:6.0.0-6-next.14",
"@verdaccio/store": "workspace:6.0.0-6-next.15",
"@verdaccio/tarball": "workspace:11.0.0-6-next.9",
"@verdaccio/utils": "workspace:6.0.0-6-next.8",
"@verdaccio/middleware": "workspace:6.0.0-6-next.15",
"@verdaccio/store": "workspace:6.0.0-6-next.16",
"@verdaccio/tarball": "workspace:11.0.0-6-next.10",
"@verdaccio/utils": "workspace:6.0.0-6-next.9",
"abortcontroller-polyfill": "1.7.3",
"cookies": "0.8.0",
"debug": "4.3.2",
@@ -57,8 +57,8 @@
"semver": "7.3.5"
},
"devDependencies": {
"@types/node": "16.9.1",
"@verdaccio/server": "workspace:6.0.0-6-next.22",
"@types/node": "16.11.6",
"@verdaccio/server": "workspace:6.0.0-6-next.23",
"@verdaccio/types": "workspace:11.0.0-6-next.9",
"@verdaccio/helper": "1.0.0",
"body-parser": "1.19.0",

View File

@@ -1,12 +1,13 @@
import mime from 'mime';
import _ from 'lodash';
import { Router } from 'express';
import _ from 'lodash';
import mime from 'mime';
import { media, allow } from '@verdaccio/middleware';
import { constants, VerdaccioError } from '@verdaccio/core';
import { Package } from '@verdaccio/types';
import { Storage } from '@verdaccio/store';
import { IAuth } from '@verdaccio/auth';
import { VerdaccioError, constants } from '@verdaccio/core';
import { allow, media } from '@verdaccio/middleware';
import { Storage } from '@verdaccio/store';
import { Package } from '@verdaccio/types';
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';
export default function (route: Router, auth: IAuth, storage: Storage): void {

View File

@@ -1,28 +1,29 @@
import bodyParser from 'body-parser';
import express, { Router } from 'express';
import semver from 'semver';
import { IAuth } from '@verdaccio/auth';
import {
antiLoop,
encodeScopePackage,
match,
validateName,
validatePackage,
encodeScopePackage,
antiLoop,
} from '@verdaccio/middleware';
import { IAuth } from '@verdaccio/auth';
import { Storage } from '@verdaccio/store';
import { Config } from '@verdaccio/types';
import bodyParser from 'body-parser';
import semver from 'semver';
import whoami from './whoami';
import ping from './ping';
import user from './user';
import distTags from './dist-tags';
import pkg from './package';
import ping from './ping';
import publish from './publish';
import search from './search';
import pkg from './package';
import stars from './stars';
import user from './user';
import profile from './v1/profile';
import token from './v1/token';
import v1Search from './v1/search';
import token from './v1/token';
import whoami from './whoami';
if (semver.lte(process.version, 'v15.0.0')) {
global.AbortController = require('abortcontroller-polyfill/dist/cjs-ponyfill').AbortController;

View File

@@ -1,15 +1,16 @@
import _ from 'lodash';
import { Router } from 'express';
import buildDebug from 'debug';
import { Router } from 'express';
import _ from 'lodash';
import { allow } from '@verdaccio/middleware';
import { getVersion } from '@verdaccio/utils';
import { HEADERS, DIST_TAGS, API_ERROR, errorUtils } from '@verdaccio/core';
import { Config, Package } from '@verdaccio/types';
import { IAuth } from '@verdaccio/auth';
import { API_ERROR, DIST_TAGS, HEADERS, errorUtils } from '@verdaccio/core';
import { allow } from '@verdaccio/middleware';
import { Storage } from '@verdaccio/store';
import { convertDistRemoteToLocalTarballUrls } from '@verdaccio/tarball';
import { $RequestExtend, $ResponseExtend, $NextFunctionVer } from '../types/custom';
import { Config, Package } from '@verdaccio/types';
import { getVersion } from '@verdaccio/utils';
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';
const debug = buildDebug('verdaccio:api:package');
@@ -40,7 +41,7 @@ export default function (route: Router, auth: IAuth, storage: Storage, config: C
route.get(
'/:package/:version?',
can('access'),
function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
function (req: $RequestExtend, _res: $ResponseExtend, next: $NextFunctionVer): void {
debug('init package by version');
const name = req.params.package;
const getPackageMetaCallback = function (err, metadata: Package): void {
@@ -49,7 +50,11 @@ export default function (route: Router, auth: IAuth, storage: Storage, config: C
return next(err);
}
debug('convert dist remote to local with prefix %o', config?.url_prefix);
metadata = convertDistRemoteToLocalTarballUrls(metadata, req, config?.url_prefix);
metadata = convertDistRemoteToLocalTarballUrls(
metadata,
{ protocol: req.protocol, headers: req.headers as any, host: req.host },
config?.url_prefix
);
let queryVersion = req.params.version;
debug('query by param version: %o', queryVersion);

View File

@@ -1,5 +1,6 @@
import { Router } from 'express';
import { $RequestExtend, $ResponseExtend, $NextFunctionVer } from '../types/custom';
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';
export default function (route: Router): void {
route.get(

View File

@@ -1,26 +1,26 @@
import Path from 'path';
import buildDebug from 'debug';
import { Router } from 'express';
import _ from 'lodash';
import mime from 'mime';
import { Router } from 'express';
import buildDebug from 'debug';
import Path from 'path';
import { IAuth } from '@verdaccio/auth';
import {
API_MESSAGE,
HEADERS,
DIST_TAGS,
API_ERROR,
API_MESSAGE,
DIST_TAGS,
HEADERS,
HTTP_STATUS,
errorUtils,
} from '@verdaccio/core';
import { validateMetadata, isObject, hasDiffOneKey } from '@verdaccio/utils';
import { media, expectJson, allow } from '@verdaccio/middleware';
import { notify } from '@verdaccio/hooks';
import { Config, Callback, MergeTags, Version, Package, CallbackAction } from '@verdaccio/types';
import { logger } from '@verdaccio/logger';
import { IAuth } from '@verdaccio/auth';
import { allow, expectJson, media } from '@verdaccio/middleware';
import { Storage } from '@verdaccio/store';
import { $RequestExtend, $ResponseExtend, $NextFunctionVer } from '../types/custom';
import { Callback, CallbackAction, Config, MergeTags, Package, Version } from '@verdaccio/types';
import { hasDiffOneKey, isObject, validateMetadata } from '@verdaccio/utils';
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';
import star from './star';
import { isPublishablePackage, isRelatedToDeprecation } from './utils';

View File

@@ -1,10 +1,11 @@
import { USERS, HTTP_STATUS } from '@verdaccio/core';
import buildDebug from 'debug';
import { Response } from 'express';
import _ from 'lodash';
import buildDebug from 'debug';
import { HTTP_STATUS, USERS } from '@verdaccio/core';
import { Storage } from '@verdaccio/store';
import { $RequestExtend, $NextFunctionVer } from '../types/custom';
import { $NextFunctionVer, $RequestExtend } from '../types/custom';
const debug = buildDebug('verdaccio:api:publish:star');

View File

@@ -1,11 +1,11 @@
import _ from 'lodash';
import { Response, Router } from 'express';
import _ from 'lodash';
import { USERS, HTTP_STATUS } from '@verdaccio/core';
import { HTTP_STATUS, USERS } from '@verdaccio/core';
import { Storage } from '@verdaccio/store';
import { Package } from '@verdaccio/types';
import { Storage } from '@verdaccio/store';
import { $RequestExtend, $NextFunctionVer } from '../types/custom';
import { $NextFunctionVer, $RequestExtend } from '../types/custom';
type Packages = Package[];

View File

@@ -1,16 +1,16 @@
import _ from 'lodash';
import { Response, Router } from 'express';
import buildDebug from 'debug';
import { Response, Router } from 'express';
import _ from 'lodash';
import { getAuthenticatedMessage, validatePassword } from '@verdaccio/utils';
import { getApiToken } from '@verdaccio/auth';
import { logger } from '@verdaccio/logger';
import { createRemoteUser } from '@verdaccio/config';
import { Config, RemoteUser } from '@verdaccio/types';
import { IAuth } from '@verdaccio/auth';
import { createRemoteUser } from '@verdaccio/config';
import { API_ERROR, API_MESSAGE, HTTP_STATUS, errorUtils } from '@verdaccio/core';
import { $RequestExtend, $NextFunctionVer } from '../types/custom';
import { logger } from '@verdaccio/logger';
import { Config, RemoteUser } from '@verdaccio/types';
import { getAuthenticatedMessage, validatePassword } from '@verdaccio/utils';
import { $NextFunctionVer, $RequestExtend } from '../types/custom';
const debug = buildDebug('verdaccio:api:user');

View File

@@ -1,6 +1,7 @@
import { Package } from '@verdaccio/types';
import _ from 'lodash';
import { Package } from '@verdaccio/types';
/**
* Check whether the package metadta has enough data to be published
* @param pkg metadata

View File

@@ -1,10 +1,11 @@
import _ from 'lodash';
import { Response, Router } from 'express';
import _ from 'lodash';
import { IAuth } from '@verdaccio/auth';
import { API_ERROR, APP_ERROR, HTTP_STATUS, SUPPORT_ERRORS, errorUtils } from '@verdaccio/core';
import { validatePassword } from '@verdaccio/utils';
import { IAuth } from '@verdaccio/auth';
import { $RequestExtend, $NextFunctionVer } from '../../types/custom';
import { $NextFunctionVer, $RequestExtend } from '../../types/custom';
export interface Profile {
tfa: boolean;

View File

@@ -1,8 +1,9 @@
import _ from 'lodash';
import buildDebug from 'debug';
import { logger } from '@verdaccio/logger';
import _ from 'lodash';
import { IAuth } from '@verdaccio/auth';
import { HTTP_STATUS, searchUtils } from '@verdaccio/core';
import { logger } from '@verdaccio/logger';
import { Storage } from '@verdaccio/store';
import { Package } from '@verdaccio/types';

View File

@@ -1,14 +1,15 @@
import _ from 'lodash';
import { errorUtils, HTTP_STATUS, SUPPORT_ERRORS } from '@verdaccio/core';
import { stringToMD5, mask } from '@verdaccio/utils';
import { getApiToken } from '@verdaccio/auth';
import { logger } from '@verdaccio/logger';
import { Response, Router } from 'express';
import _ from 'lodash';
import { Config, RemoteUser, Token } from '@verdaccio/types';
import { getApiToken } from '@verdaccio/auth';
import { IAuth } from '@verdaccio/auth';
import { HTTP_STATUS, SUPPORT_ERRORS, errorUtils } from '@verdaccio/core';
import { logger } from '@verdaccio/logger';
import { Storage } from '@verdaccio/store';
import { $RequestExtend, $NextFunctionVer } from '../../types/custom';
import { Config, RemoteUser, Token } from '@verdaccio/types';
import { mask, stringToMD5 } from '@verdaccio/utils';
import { $NextFunctionVer, $RequestExtend } from '../../types/custom';
export type NormalizeToken = Token & {
created: string;

View File

@@ -1,6 +1,7 @@
import { Response, Router } from 'express';
import buildDebug from 'debug';
import { $RequestExtend, $NextFunctionVer } from '../types/custom';
import { Response, Router } from 'express';
import { $NextFunctionVer, $RequestExtend } from '../types/custom';
const debug = buildDebug('verdaccio:api:user');

View File

@@ -1,14 +1,15 @@
import path from 'path';
import express, { Application } from 'express';
import supertest from 'supertest';
import bodyParser from 'body-parser';
import express, { Application } from 'express';
import path from 'path';
import supertest from 'supertest';
import { Config, parseConfigFile } from '@verdaccio/config';
import { Storage } from '@verdaccio/store';
import { generatePackageMetadata } from '@verdaccio/helper';
import { final, handleError, errorReportingMiddleware } from '@verdaccio/middleware';
import { Auth, IAuth } from '@verdaccio/auth';
import { Config, parseConfigFile } from '@verdaccio/config';
import { HEADERS, HEADER_TYPE, HTTP_STATUS } from '@verdaccio/core';
import { generatePackageMetadata } from '@verdaccio/helper';
import { errorReportingMiddleware, final, handleError } from '@verdaccio/middleware';
import { Storage } from '@verdaccio/store';
import apiEndpoints from '../../src';
const getConf = (conf) => {

View File

@@ -1,7 +1,8 @@
import supertest from 'supertest';
import { HEADER_TYPE, HEADERS, HTTP_STATUS } from '@verdaccio/core';
import { $ResponseExtend, $RequestExtend } from '../../types/custom';
import { HEADERS, HEADER_TYPE, HTTP_STATUS } from '@verdaccio/core';
import { $RequestExtend, $ResponseExtend } from '../../types/custom';
import { initializeServer, publishTaggedVersion, publishVersion } from './_helper';
const mockApiJWTmiddleware = jest.fn(

View File

@@ -1,6 +1,7 @@
import supertest from 'supertest';
import { HEADER_TYPE, HEADERS, HTTP_STATUS } from '@verdaccio/core';
import { HEADERS, HEADER_TYPE, HTTP_STATUS } from '@verdaccio/core';
import { initializeServer } from './_helper';
describe('ping', () => {

View File

@@ -1,8 +1,10 @@
import { HTTP_STATUS } from '@verdaccio/core';
import supertest from 'supertest';
import { API_ERROR, API_MESSAGE, HEADER_TYPE, HEADERS } from '@verdaccio/core';
import { HTTP_STATUS } from '@verdaccio/core';
import { API_ERROR, API_MESSAGE, HEADERS, HEADER_TYPE } from '@verdaccio/core';
import { generatePackageMetadata } from '@verdaccio/helper';
import { $ResponseExtend, $RequestExtend } from '../../types/custom';
import { $RequestExtend, $ResponseExtend } from '../../types/custom';
import { initializeServer, publishVersion } from './_helper';
const mockApiJWTmiddleware = jest.fn(

View File

@@ -1,13 +1,13 @@
import supertest from 'supertest';
import _ from 'lodash';
import supertest from 'supertest';
import {
errorUtils,
API_ERROR,
API_MESSAGE,
HEADERS,
HEADER_TYPE,
API_MESSAGE,
HTTP_STATUS,
API_ERROR,
errorUtils,
} from '@verdaccio/core';
import { $RequestExtend, $ResponseExtend } from '../../types/custom';

View File

@@ -1,10 +1,11 @@
import { errorUtils, HTTP_STATUS, API_ERROR } from '@verdaccio/core';
import { API_ERROR, HTTP_STATUS, errorUtils } from '@verdaccio/core';
import {
addVersion,
uploadPackageTarball,
publishPackage,
removeTarball,
unPublishPackage,
publishPackage,
uploadPackageTarball,
} from '../../src/publish';
const REVISION_MOCK = '15-e53a77096b0ee33e';

View File

@@ -1,7 +1,7 @@
/* eslint-disable curly */
// ensure that all arguments are validated
import path from 'path';
import fs from 'fs';
import path from 'path';
/**
* Validate.

View File

@@ -1,6 +1,7 @@
import { Logger, RemoteUser } from '@verdaccio/types';
import { NextFunction, Request, Response } from 'express';
import { Logger, RemoteUser } from '@verdaccio/types';
export type $RequestExtend = Request & { remote_user?: any; log: Logger };
export type $ResponseExtend = Response & { cookies?: any };
export type $NextFunctionVer = NextFunction & any;

View File

@@ -1,5 +1,18 @@
# @verdaccio/auth
## 6.0.0-6-next.15
### Minor Changes
- 20c9e43e: dist tags Implementation on Fastify
### Patch Changes
- Updated dependencies [f86c31ed]
- @verdaccio/utils@6.0.0-6-next.9
- @verdaccio/config@6.0.0-6-next.11
- @verdaccio/loaders@6.0.0-6-next.7
## 6.0.0-6-next.14
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/auth",
"version": "6.0.0-6-next.14",
"version": "6.0.0-6-next.15",
"description": "logger",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -40,10 +40,10 @@
"license": "MIT",
"dependencies": {
"@verdaccio/core": "workspace:6.0.0-6-next.3",
"@verdaccio/config": "workspace:6.0.0-6-next.10",
"@verdaccio/config": "workspace:6.0.0-6-next.11",
"@verdaccio/loaders": "workspace:6.0.0-6-next.7",
"@verdaccio/logger": "workspace:6.0.0-6-next.7",
"@verdaccio/utils": "workspace:6.0.0-6-next.8",
"@verdaccio/utils": "workspace:6.0.0-6-next.9",
"debug": "4.3.2",
"express": "4.17.1",
"jsonwebtoken": "8.5.1",
@@ -51,7 +51,7 @@
"verdaccio-htpasswd": "workspace:11.0.0-6-next.10"
},
"devDependencies": {
"@verdaccio/mock": "workspace:6.0.0-6-next.11",
"@verdaccio/mock": "workspace:6.0.0-6-next.12",
"@verdaccio/types": "workspace:11.0.0-6-next.9"
},
"funding": {

View File

@@ -1,7 +1,9 @@
import _ from 'lodash';
import { NextFunction, Request, Response } from 'express';
import buildDebug from 'debug';
import { NextFunction, Request, Response } from 'express';
import _ from 'lodash';
import { HTPasswd, HTPasswdConfig } from 'verdaccio-htpasswd';
import { createAnonymousRemoteUser, createRemoteUser } from '@verdaccio/config';
import {
API_ERROR,
SUPPORT_ERRORS,
@@ -11,38 +13,33 @@ import {
errorUtils,
} from '@verdaccio/core';
import { loadPlugin } from '@verdaccio/loaders';
import { HTPasswd, HTPasswdConfig } from 'verdaccio-htpasswd';
import {
Config,
Logger,
Callback,
IPluginAuth,
RemoteUser,
JWTSignOptions,
Security,
AuthPluginPackage,
AllowAccess,
AuthPluginPackage,
Callback,
Config,
IPluginAuth,
JWTSignOptions,
Logger,
PackageAccess,
PluginOptions,
RemoteUser,
Security,
} from '@verdaccio/types';
import { getMatchedPackagesSpec, isNil, isFunction } from '@verdaccio/utils';
import { createAnonymousRemoteUser, createRemoteUser } from '@verdaccio/config';
import {
getMiddlewareCredentials,
getDefaultPlugins,
verifyJWTPayload,
parseAuthTokenHeader,
isAuthHeaderValid,
isAESLegacy,
convertPayloadToBase64,
} from './utils';
import { getMatchedPackagesSpec, isFunction, isNil } from '@verdaccio/utils';
import { signPayload } from './jwt-token';
import { aesEncrypt } from './legacy-token';
import { parseBasicPayload } from './token';
import {
convertPayloadToBase64,
getDefaultPlugins,
getMiddlewareCredentials,
isAESLegacy,
isAuthHeaderValid,
parseAuthTokenHeader,
verifyJWTPayload,
} from './utils';
/* eslint-disable @typescript-eslint/no-var-requires */
const LoggerApi = require('@verdaccio/logger');
@@ -97,6 +94,9 @@ class Auth implements IAuth {
this.config = config;
this.logger = LoggerApi.logger.child({ sub: 'auth' });
this.secret = config.secret;
if (!this.secret) {
throw new TypeError('secret it is required value on initialize the auth class');
}
this.plugins =
_.isNil(config?.auth) === false ? this._loadPlugin(config) : this.loadDefaultPlugin(config);

View File

@@ -1,5 +1,5 @@
import jwt from 'jsonwebtoken';
import buildDebug from 'debug';
import jwt from 'jsonwebtoken';
import { JWTSignOptions, RemoteUser } from '@verdaccio/types';

View File

@@ -1,13 +1,14 @@
import {
HexBase64BinaryEncoding,
Utf8AsciiBinaryEncoding,
createCipheriv,
createDecipheriv,
HexBase64BinaryEncoding,
randomBytes,
Utf8AsciiBinaryEncoding,
} from 'crypto';
import { TOKEN_VALID_LENGTH } from '@verdaccio/config';
import buildDebug from 'debug';
import { TOKEN_VALID_LENGTH } from '@verdaccio/config';
const debug = buildDebug('verdaccio:auth:token:legacy');
export const defaultAlgorithm = process.env.VERDACCIO_LEGACY_ALGORITHM || 'aes-256-ctr';

View File

@@ -1,26 +1,27 @@
import _ from 'lodash';
import buildDebug from 'debug';
import _ from 'lodash';
import { createAnonymousRemoteUser } from '@verdaccio/config';
import {
API_ERROR,
HTTP_STATUS,
TOKEN_BASIC,
TOKEN_BEARER,
VerdaccioError,
errorUtils,
} from '@verdaccio/core';
import {
AuthPackageAllow,
Callback,
Config,
IPluginAuth,
RemoteUser,
Security,
AuthPackageAllow,
} from '@verdaccio/types';
import {
HTTP_STATUS,
TOKEN_BASIC,
TOKEN_BEARER,
API_ERROR,
VerdaccioError,
errorUtils,
} from '@verdaccio/core';
import { createAnonymousRemoteUser } from '@verdaccio/config';
import { TokenEncryption, AESPayload } from './auth';
import { aesDecrypt } from './legacy-token';
import { AESPayload, TokenEncryption } from './auth';
import { verifyPayload } from './jwt-token';
import { aesDecrypt } from './legacy-token';
import { parseBasicPayload } from './token';
const debug = buildDebug('verdaccio:auth:utils');

View File

@@ -1,43 +1,42 @@
import path from 'path';
import _ from 'lodash';
import path from 'path';
import { configExample } from '@verdaccio/mock';
import {
Config as AppConfig,
parseConfigFile,
ROLES,
createRemoteUser,
createAnonymousRemoteUser,
createRemoteUser,
parseConfigFile,
} from '@verdaccio/config';
import {
getAuthenticatedMessage,
buildToken,
AllowActionCallbackResponse,
buildUserBuffer,
} from '@verdaccio/utils';
import { Config, Security, RemoteUser } from '@verdaccio/types';
import {
VerdaccioError,
API_ERROR,
CHARACTER_ENCODING,
TOKEN_BEARER,
API_ERROR,
VerdaccioError,
errorUtils,
} from '@verdaccio/core';
import { setup } from '@verdaccio/logger';
import { configExample } from '@verdaccio/mock';
import { Config, RemoteUser, Security } from '@verdaccio/types';
import {
AllowActionCallbackResponse,
buildToken,
buildUserBuffer,
getAuthenticatedMessage,
} from '@verdaccio/utils';
import {
IAuth,
Auth,
ActionsAllowed,
Auth,
IAuth,
aesDecrypt,
allow_action,
getApiToken,
getDefaultPlugins,
getMiddlewareCredentials,
getApiToken,
verifyJWTPayload,
aesDecrypt,
verifyPayload,
signPayload,
verifyJWTPayload,
verifyPayload,
} from '../src';
setup([]);

View File

@@ -1,19 +1,21 @@
import _ from 'lodash';
import { ROLES, Config as AppConfig } from '@verdaccio/config';
import { setup } from '@verdaccio/logger';
import { IAuth } from '@verdaccio/auth';
import { Config } from '@verdaccio/types';
import { Config as AppConfig, ROLES } from '@verdaccio/config';
import { errorUtils } from '@verdaccio/core';
import { setup } from '@verdaccio/logger';
import { Config } from '@verdaccio/types';
import { Auth } from '../src';
import { authProfileConf, authPluginFailureConf, authPluginPassThrougConf } from './helper/plugin';
import { authPluginFailureConf, authPluginPassThrougConf, authProfileConf } from './helper/plugin';
setup([]);
describe('AuthTest', () => {
test('should be defined', () => {
const config: Config = new AppConfig(_.cloneDeep(authProfileConf));
config.checkSecretKey('12345');
const auth: IAuth = new Auth(config);
expect(auth).toBeDefined();
@@ -23,6 +25,7 @@ describe('AuthTest', () => {
describe('test authenticate states', () => {
test('should be a success login', () => {
const config: Config = new AppConfig(_.cloneDeep(authProfileConf));
config.checkSecretKey('12345');
const auth: IAuth = new Auth(config);
expect(auth).toBeDefined();
@@ -49,6 +52,7 @@ describe('AuthTest', () => {
test('should be a fail on login', () => {
const config: Config = new AppConfig(_.cloneDeep(authPluginFailureConf));
config.checkSecretKey('12345');
const auth: IAuth = new Auth(config);
expect(auth).toBeDefined();
@@ -67,6 +71,7 @@ describe('AuthTest', () => {
describe('test authenticate out of control inputs from plugins', () => {
test('should skip falsy values', () => {
const config: Config = new AppConfig(_.cloneDeep(authPluginPassThrougConf));
config.checkSecretKey('12345');
const auth: IAuth = new Auth(config);
expect(auth).toBeDefined();
@@ -86,6 +91,7 @@ describe('AuthTest', () => {
test('should error truthy non-array', () => {
const config: Config = new AppConfig(_.cloneDeep(authPluginPassThrougConf));
config.checkSecretKey('12345');
const auth: IAuth = new Auth(config);
expect(auth).toBeDefined();
@@ -103,6 +109,7 @@ describe('AuthTest', () => {
test('should skip empty array', () => {
const config: Config = new AppConfig(_.cloneDeep(authPluginPassThrougConf));
config.checkSecretKey('12345');
const auth: IAuth = new Auth(config);
expect(auth).toBeDefined();
@@ -119,6 +126,7 @@ describe('AuthTest', () => {
test('should accept valid array', () => {
const config: Config = new AppConfig(_.cloneDeep(authPluginPassThrougConf));
config.checkSecretKey('12345');
const auth: IAuth = new Auth(config);
expect(auth).toBeDefined();

View File

@@ -1,4 +1,5 @@
import path from 'path';
import { configExample as config } from '@verdaccio/mock';
export const authProfileConf = config({

View File

@@ -1,5 +1,15 @@
# @verdaccio/cli
## 6.0.0-6-next.25
### Patch Changes
- Updated dependencies [f86c31ed]
- Updated dependencies [20c9e43e]
- @verdaccio/fastify-migration@6.0.0-6-next.16
- @verdaccio/config@6.0.0-6-next.11
- @verdaccio/node-api@6.0.0-6-next.24
## 6.0.0-6-next.24
### Minor Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/cli",
"version": "6.0.0-6-next.24",
"version": "6.0.0-6-next.25",
"author": {
"name": "Juan Picado",
"email": "juanpicado19@gmail.com"
@@ -45,10 +45,10 @@
},
"dependencies": {
"@verdaccio/core": "workspace:6.0.0-6-next.3",
"@verdaccio/config": "workspace:6.0.0-6-next.10",
"@verdaccio/config": "workspace:6.0.0-6-next.11",
"@verdaccio/logger": "workspace:6.0.0-6-next.7",
"@verdaccio/node-api": "workspace:6.0.0-6-next.23",
"@verdaccio/fastify-migration": "workspace:6.0.0-6-next.15",
"@verdaccio/node-api": "workspace:6.0.0-6-next.24",
"@verdaccio/fastify-migration": "workspace:6.0.0-6-next.16",
"clipanion": "3.1.0",
"envinfo": "7.8.1",
"kleur": "3.0.3",

View File

@@ -1,11 +1,12 @@
import { Cli } from 'clipanion';
import { warningUtils } from '@verdaccio/core';
import { FastifyServer } from './commands/FastifyServer';
import { InfoCommand } from './commands/info';
import { InitCommand } from './commands/init';
import { VersionCommand } from './commands/version';
import { FastifyServer } from './commands/FastifyServer';
import { isVersionValid, MIN_NODE_VERSION } from './utils';
import { MIN_NODE_VERSION, isVersionValid } from './utils';
if (process.getuid && process.getuid() === 0) {
warningUtils.emit(warningUtils.Codes.VERWAR001);

View File

@@ -1,7 +1,9 @@
import { Command, Option } from 'clipanion';
import { findConfigFile, parseConfigFile } from '@verdaccio/config';
import { setup, logger } from '@verdaccio/logger';
import { warningUtils } from '@verdaccio/core';
import server from '@verdaccio/fastify-migration';
import { logger, setup } from '@verdaccio/logger';
import { ConfigRuntime } from '@verdaccio/types';
export const DEFAULT_PROCESS_NAME: string = 'verdaccio';
@@ -27,7 +29,7 @@ export class FastifyServer extends Command {
private initLogger(logConfig: ConfigRuntime) {
try {
if (logConfig.logs) {
process.emitWarning('config.logs is deprecated, rename configuration to "config.log"');
warningUtils.emit(warningUtils.Codes.VERDEP001);
}
// FUTURE: remove fallback when is ready
setup(logConfig.log || logConfig.logs);

View File

@@ -1,5 +1,5 @@
import envinfo from 'envinfo';
import { Command } from 'clipanion';
import envinfo from 'envinfo';
export class InfoCommand extends Command {
public static paths = [[`--info`], [`-i`]];

View File

@@ -1,9 +1,10 @@
import { Command, Option } from 'clipanion';
import { findConfigFile, parseConfigFile } from '@verdaccio/config';
import { setup, logger } from '@verdaccio/logger';
import { warningUtils } from '@verdaccio/core';
import { logger, setup } from '@verdaccio/logger';
import { initServer } from '@verdaccio/node-api';
import { ConfigRuntime } from '@verdaccio/types';
import { warningUtils } from '@verdaccio/core';
export const DEFAULT_PROCESS_NAME: string = 'verdaccio';

View File

@@ -1,5 +1,12 @@
# @verdaccio/config
## 6.0.0-6-next.11
### Patch Changes
- Updated dependencies [f86c31ed]
- @verdaccio/utils@6.0.0-6-next.9
## 6.0.0-6-next.10
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/config",
"version": "6.0.0-6-next.10",
"version": "6.0.0-6-next.11",
"description": "logger",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -40,7 +40,7 @@
},
"dependencies": {
"@verdaccio/core": "workspace:6.0.0-6-next.3",
"@verdaccio/utils": "workspace:6.0.0-6-next.8",
"@verdaccio/utils": "workspace:6.0.0-6-next.9",
"debug": "4.3.2",
"js-yaml": "3.14.1",
"lodash": "4.17.21",

View File

@@ -1,10 +1,11 @@
import fs from 'fs';
import path from 'path';
import _ from 'lodash';
import buildDebug from 'debug';
import fs from 'fs';
import _ from 'lodash';
import path from 'path';
import { CHARACTER_ENCODING } from '@verdaccio/core';
import { folderExists, fileExists } from './config-utils';
import { fileExists, folderExists } from './config-utils';
const CONFIG_FILE = 'config.yaml';
const XDG = 'xdg';

View File

@@ -1,25 +1,25 @@
import assert from 'assert';
import _ from 'lodash';
import buildDebug from 'debug';
import _ from 'lodash';
import { getMatchedPackagesSpec, generateRandomHexString, isObject } from '@verdaccio/utils';
import { APP_ERROR } from '@verdaccio/core';
import {
PackageList,
Config as AppConfig,
ConfigRuntime,
Security,
PackageAccess,
ServerSettingsConf,
AuthConf,
ConfigRuntime,
PackageAccess,
PackageList,
Security,
ServerSettingsConf,
} from '@verdaccio/types';
import { generateRandomHexString, getMatchedPackagesSpec, isObject } from '@verdaccio/utils';
import { generateRandomSecretKey } from './token';
import { normalisePackageAccess } from './package-access';
import { sanityCheckUplinksProps, uplinkSanityCheck } from './uplinks';
import { defaultSecurity } from './security';
import { getUserAgent } from './agent';
import { normalisePackageAccess } from './package-access';
import { defaultSecurity } from './security';
import serverSettings from './serverSettings';
import { generateRandomSecretKey } from './token';
import { sanityCheckUplinksProps, uplinkSanityCheck } from './uplinks';
const strategicConfigProps = ['uplinks', 'packages'];
const allowedEnvConfig = ['http_proxy', 'https_proxy', 'no_proxy'];

View File

@@ -1,7 +1,9 @@
import assert from 'assert';
import _ from 'lodash';
import { PackageAccess } from '@verdaccio/types';
import { errorUtils } from '@verdaccio/core';
import { PackageAccess } from '@verdaccio/types';
export interface LegacyPackageList {
[key: string]: PackageAccess;
}

View File

@@ -1,5 +1,6 @@
import fs from 'fs';
import YAML from 'js-yaml';
import { APP_ERROR } from '@verdaccio/core';
import { ConfigRuntime, ConfigYaml } from '@verdaccio/types';

View File

@@ -1,8 +1,9 @@
import assert from 'assert';
import { getMatchedPackagesSpec } from '@verdaccio/utils';
import { PackageList, UpLinksConfList } from '@verdaccio/types';
import _ from 'lodash';
import { PackageList, UpLinksConfList } from '@verdaccio/types';
import { getMatchedPackagesSpec } from '@verdaccio/utils';
export const DEFAULT_REGISTRY = 'https://registry.npmjs.org';
export const DEFAULT_UPLINK = 'npmjs';

View File

@@ -1,4 +1,5 @@
import os from 'os';
import { findConfigFile } from '../src/config-path';
const mockmkDir = jest.fn();

View File

@@ -1,14 +1,14 @@
import path from 'path';
import _ from 'lodash';
import path from 'path';
import {
Config,
DEFAULT_REGISTRY,
DEFAULT_UPLINK,
defaultSecurity,
parseConfigFile,
ROLES,
WEB_TITLE,
defaultSecurity,
parseConfigFile,
} from '../src';
import { parseConfigurationFile } from './utils';

View File

@@ -1,7 +1,7 @@
import _ from 'lodash';
import { normalisePackageAccess, PACKAGE_ACCESS } from '../src/package-access';
import { parseConfigFile } from '../src';
import { PACKAGE_ACCESS, normalisePackageAccess } from '../src/package-access';
import { parseConfigurationFile } from './utils';
describe('Package access utilities', () => {

View File

@@ -1,4 +1,4 @@
import { generateRandomSecretKey, TOKEN_VALID_LENGTH } from '../src/token';
import { TOKEN_VALID_LENGTH, generateRandomSecretKey } from '../src/token';
test('token test valid length', () => {
const token = generateRandomSecretKey();

View File

@@ -1,5 +1,5 @@
import { hasProxyTo, sanityCheckUplinksProps, uplinkSanityCheck } from '../src/uplinks';
import { normalisePackageAccess, parseConfigFile } from '../src';
import { hasProxyTo, sanityCheckUplinksProps, uplinkSanityCheck } from '../src/uplinks';
import { parseConfigurationFile } from './utils';
describe('Uplinks Utilities', () => {

View File

@@ -1,5 +1,5 @@
import { ROLES, createAnonymousRemoteUser, createRemoteUser } from '../src';
import { spliceURL } from '../src/string';
import { createAnonymousRemoteUser, createRemoteUser, ROLES } from '../src';
describe('spliceURL', () => {
test('should splice two strings and generate a url', () => {

View File

@@ -1,4 +1,5 @@
import createError, { HttpError } from 'http-errors';
import { DEFAULT_MIN_LIMIT_PASSWORD, HTTP_STATUS } from './constants';
export const API_ERROR = {

View File

@@ -1,11 +1,11 @@
import * as searchUtils from './search-utils';
import * as streamUtils from './stream-utils';
import * as errorUtils from './error-utils';
import * as validatioUtils from './validation-utils';
import * as constants from './constants';
import * as pluginUtils from './plugin-utils';
import * as errorUtils from './error-utils';
import * as fileUtils from './file-utils';
import * as pkgUtils from './pkg-utils';
import * as pluginUtils from './plugin-utils';
import * as searchUtils from './search-utils';
import * as streamUtils from './stream-utils';
import * as validatioUtils from './validation-utils';
import * as warningUtils from './warning-utils';
export { VerdaccioError, API_ERROR, SUPPORT_ERRORS, APP_ERROR } from './error-utils';

View File

@@ -1,5 +1,7 @@
import { Package } from '@verdaccio/types';
import semver from 'semver';
import { Package } from '@verdaccio/types';
import { DIST_TAGS } from './constants';
/**

View File

@@ -1,4 +1,5 @@
import { Config, IPackageStorage, Token, TokenFilter } from '@verdaccio/types';
import { searchUtils } from '.';
interface IPlugin {

View File

@@ -1,4 +1,4 @@
import { PassThrough, TransformOptions, Transform } from 'stream';
import { PassThrough, Transform, TransformOptions } from 'stream';
export interface IReadTarball {
abort?: () => void;

View File

@@ -1,5 +1,7 @@
import assert from 'assert';
import { Package } from '@verdaccio/types';
import { DIST_TAGS } from './constants';
export function isPackageNameScoped(name: string): boolean {

View File

@@ -1,17 +1,17 @@
import _ from 'lodash';
import { HTTP_STATUS } from '../src/constants';
import { HTTP_STATUS } from '../src/constants';
import {
getNotFound,
VerdaccioError,
getConflict,
getBadData,
getInternalError,
API_ERROR,
getUnauthorized,
getForbidden,
getServiceUnavailable,
VerdaccioError,
getBadData,
getCode,
getConflict,
getForbidden,
getInternalError,
getNotFound,
getServiceUnavailable,
getUnauthorized,
} from '../src/error-utils';
describe('testing errors', () => {

View File

@@ -1,4 +1,4 @@
import { semverSort, mergeVersions } from '../src/pkg-utils';
import { mergeVersions, semverSort } from '../src/pkg-utils';
describe('Storage._merge_versions versions', () => {
test('simple', () => {

View File

@@ -1,5 +1,6 @@
import { Stream } from 'stream';
import { readableToString, ReadTarball, UploadTarball } from '../src/stream-utils';
import { ReadTarball, UploadTarball, readableToString } from '../src/stream-utils';
describe('mystreams', () => {
test('should delay events on ReadTarball abort', (cb) => {

View File

@@ -1,4 +1,4 @@
import { validateName, validatePackage, isObject } from '../src/validation-utils';
import { isObject, validateName, validatePackage } from '../src/validation-utils';
describe('validatePackage', () => {
test('should validate package names', () => {

View File

@@ -1,4 +1,5 @@
import locker from 'lockfile';
import { Callback } from '@verdaccio/types';
// unlocks file by removing existing lock file

View File

@@ -1,7 +1,6 @@
import fs from 'fs';
import path from 'path';
import locker from 'lockfile';
import path from 'path';
export const statDir = (name: string): Promise<Error | null> => {
return new Promise((resolve, reject): void => {

View File

@@ -1,7 +1,7 @@
import path from 'path';
import fs from 'fs';
import path from 'path';
import { lockFile, unlockFile, readFile } from '../src/index';
import { lockFile, readFile, unlockFile } from '../src/index';
interface Error {
message: string;

View File

@@ -1,6 +1,6 @@
import marked from 'marked';
import createDOMPurify from 'dompurify';
import { JSDOM } from 'jsdom';
import marked from 'marked';
const DOMPurify = createDOMPurify(new JSDOM('').window);

View File

@@ -1,5 +1,25 @@
# @verdaccio/fastify-migration
## 6.0.0-6-next.16
### Minor Changes
- f86c31ed: feat: migrate web sidebar endpoint to fastify
reuse utils methods between packages
- 20c9e43e: dist tags Implementation on Fastify
### Patch Changes
- Updated dependencies [f86c31ed]
- Updated dependencies [20c9e43e]
- @verdaccio/store@6.0.0-6-next.16
- @verdaccio/utils@6.0.0-6-next.9
- @verdaccio/auth@6.0.0-6-next.15
- @verdaccio/config@6.0.0-6-next.11
- @verdaccio/tarball@11.0.0-6-next.10
## 6.0.0-6-next.15
### Patch Changes

View File

@@ -1,7 +1,9 @@
import path from 'path';
import buildDebug from 'debug';
import path from 'path';
import { parseConfigFile } from '@verdaccio/config';
import { setup, logger } from '@verdaccio/logger';
import { logger, setup } from '@verdaccio/logger';
import server from '../src/index';
const debug = buildDebug('verdaccio:fastify:debug');

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/fastify-migration",
"version": "6.0.0-6-next.15",
"version": "6.0.0-6-next.16",
"description": "Fastify server migration package",
"keywords": [
"private",
@@ -35,12 +35,13 @@
},
"dependencies": {
"@verdaccio/core": "workspace:6.0.0-6-next.3",
"@verdaccio/config": "workspace:6.0.0-6-next.10",
"@verdaccio/auth": "workspace:6.0.0-6-next.14",
"@verdaccio/config": "workspace:6.0.0-6-next.11",
"@verdaccio/auth": "workspace:6.0.0-6-next.15",
"@verdaccio/logger": "workspace:6.0.0-6-next.7",
"@verdaccio/store": "workspace:6.0.0-6-next.15",
"@verdaccio/tarball": "workspace:11.0.0-6-next.9",
"@verdaccio/utils": "workspace:6.0.0-6-next.8",
"@verdaccio/store": "workspace:6.0.0-6-next.16",
"@verdaccio/tarball": "workspace:11.0.0-6-next.10",
"@verdaccio/utils": "workspace:6.0.0-6-next.9",
"@verdaccio/readme": "workspace:11.0.0-6-next.4",
"abortcontroller-polyfill": "1.7.3",
"core-js": "3.17.2",
"debug": "4.3.2",
@@ -50,7 +51,7 @@
"semver": "7.3.5"
},
"devDependencies": {
"@types/node": "16.9.1",
"@types/node": "16.11.6",
"@verdaccio/types": "workspace:11.0.0-6-next.9",
"ts-node": "10.2.1"
},

View File

@@ -0,0 +1,55 @@
import buildDebug from 'debug';
import { FastifyInstance } from 'fastify';
const debug = buildDebug('verdaccio:api:dist-tags');
async function distTagsRoute(fastify: FastifyInstance) {
fastify.get('/-/package/:packageName/dist-tags', async (request, reply) => {
// @ts-ignore
const { packageName } = request.params;
debug('dist-tags: response %o', packageName);
fastify.storage.getPackage({
name: packageName,
uplinksLook: true,
req: request.raw,
callback: function (err, info): void {
if (err) {
reply.send(err);
}
reply.code(fastify.statusCode.OK).send(info[fastify.constants.DIST_TAGS]);
},
});
});
fastify.post('/-/package/:packageName/dist-tags', async (request, reply) => {
// @ts-ignore
const { packageName } = request.params;
// @ts-ignore
fastify.storage.mergeTags(packageName, request.body, function (err): void {
if (err) {
reply.send(err);
}
reply
.code(fastify.statusCode.CREATED)
.send({ ok: fastify.constants.API_MESSAGE.TAG_UPDATED });
});
});
fastify.delete('/-/package/:packageName/dist-tags', async (request, reply) => {
// @ts-ignore
const { packageName } = request.params;
fastify.storage.getPackage({
name: packageName,
uplinksLook: true,
req: request.raw,
callback: function (err, info): void {
if (err) {
reply.send(err);
}
reply.send(info[fastify.constants.DIST_TAGS]);
},
});
});
}
export default distTagsRoute;

View File

@@ -1,8 +1,10 @@
/* eslint-disable no-console */
/* eslint-disable no-invalid-this */
import { logger } from '@verdaccio/logger';
import { FastifyInstance } from 'fastify';
import { logger } from '@verdaccio/logger';
async function pingRoute(fastify: FastifyInstance) {
fastify.get('/-/ping', async () => {
logger.http('ping endpoint');

View File

@@ -1,8 +1,10 @@
/* eslint-disable no-console */
/* eslint-disable no-invalid-this */
import { logger } from '@verdaccio/logger';
import { FastifyInstance } from 'fastify';
import { logger } from '@verdaccio/logger';
async function searchRoute(fastify: FastifyInstance) {
fastify.get('/-/v1/search', async (request, reply) => {
// TODO: apply security layer here like in

View File

@@ -0,0 +1,24 @@
import buildDebug from 'debug';
import { FastifyInstance } from 'fastify';
const debug = buildDebug('verdaccio:api:tarball');
async function tarballRoute(fastify: FastifyInstance) {
fastify.get('/:package/-/:filename', async (request, reply) => {
// @ts-ignore
const { package: pkg, filename } = request.params;
debug('stream tarball for %s@%s', pkg, filename);
const stream = fastify.storage.getTarball(pkg, filename);
return reply.send(stream);
});
fastify.get('/:scopedPackage/-/:scope/:filename', async (request, reply) => {
// @ts-ignore
const { scopedPackage, filename } = request.params;
debug('stream scope tarball for %s@%s', scopedPackage, filename);
const stream = fastify.storage.getTarball(scopedPackage, filename);
return reply.send(stream);
});
}
export default tarballRoute;

View File

@@ -1,13 +1,15 @@
/* eslint-disable no-console */
/* eslint-disable no-invalid-this */
import _ from 'lodash';
import { getAuthenticatedMessage, validatePassword } from '@verdaccio/utils';
import { RemoteUser } from '@verdaccio/types';
import { logger } from '@verdaccio/logger';
import { createRemoteUser } from '@verdaccio/config';
import { getApiToken } from '@verdaccio/auth';
import buildDebug from 'debug';
import { FastifyInstance, FastifyRequest } from 'fastify';
import _ from 'lodash';
import { getApiToken } from '@verdaccio/auth';
import { createRemoteUser } from '@verdaccio/config';
import { logger } from '@verdaccio/logger';
import { RemoteUser } from '@verdaccio/types';
import { getAuthenticatedMessage, validatePassword } from '@verdaccio/utils';
const debug = buildDebug('verdaccio:api:user');
@@ -16,7 +18,7 @@ async function userRoute(fastify: FastifyInstance) {
// @ts-expect-error
const message = getAuthenticatedMessage(request.userRemote.name);
logger.info('user authenticated message %o', message);
reply.code(fastify.httpStatuscode.OK);
reply.code(fastify.statusCode.OK);
return { ok: message };
});
@@ -28,7 +30,7 @@ async function userRoute(fastify: FastifyInstance) {
const userRemote: RemoteUser = request.userRemote;
await fastify.auth.invalidateToken(token);
console.log('userRoute', userRemote);
reply.code(fastify.httpStatuscode.OK);
reply.code(fastify.statusCode.OK);
return { ok: fastify.apiMessage.LOGGED_OUT };
});
@@ -50,10 +52,10 @@ async function userRoute(fastify: FastifyInstance) {
'authenticating for user @{username} failed. Error: @{err.message}'
);
reply
.code(fastify.httpStatuscode.UNAUTHORIZED)
.code(fastify.statusCode.UNAUTHORIZED)
.send(
fastify.errorUtils.getCode(
fastify.httpStatuscode.UNAUTHORIZED,
fastify.statusCode.UNAUTHORIZED,
fastify.apiError.BAD_USERNAME_PASSWORD
)
);
@@ -69,7 +71,7 @@ async function userRoute(fastify: FastifyInstance) {
if (!token) {
return reply.send(fastify.errorUtils.getUnauthorized());
} else {
reply.code(fastify.httpStatuscode.CREATED);
reply.code(fastify.statusCode.CREATED);
const message = getAuthenticatedMessage(remoteName);
debug('login: created user message %o', message);
reply.send({
@@ -82,9 +84,9 @@ async function userRoute(fastify: FastifyInstance) {
} else {
if (validatePassword(password) === false) {
debug('adduser: invalid password');
reply.code(fastify.httpStatuscode.BAD_REQUEST).send(
reply.code(fastify.statusCode.BAD_REQUEST).send(
fastify.errorUtils.getCode(
fastify.httpStatuscode.BAD_REQUEST,
fastify.statusCode.BAD_REQUEST,
// eslint-disable-next-line new-cap
fastify.apiError.PASSWORD_SHORT()
)
@@ -94,8 +96,8 @@ async function userRoute(fastify: FastifyInstance) {
fastify.auth.add_user(name, password, async function (err, user): Promise<void> {
if (err) {
if (
err.status >= fastify.httpStatuscode.BAD_REQUEST &&
err.status < fastify.httpStatuscode.INTERNAL_ERROR
err.status >= fastify.statusCode.BAD_REQUEST &&
err.status < fastify.statusCode.INTERNAL_ERROR
) {
debug('adduser: error on create user');
// With npm registering is the same as logging in,
@@ -118,7 +120,7 @@ async function userRoute(fastify: FastifyInstance) {
return reply.send(fastify.errorUtils.getUnauthorized());
}
debug('adduser: user has been created');
reply.code(fastify.httpStatuscode.CREATED).send({
reply.code(fastify.statusCode.CREATED).send({
ok: `user '${name}' created`,
token,
});

View File

@@ -0,0 +1,15 @@
import buildDebug from 'debug';
import { FastifyInstance } from 'fastify';
const debug = buildDebug('verdaccio:api:whoami');
async function whoamiRoute(fastify: FastifyInstance) {
fastify.get('/-/whoami', async (request, reply) => {
const username: string | void = request.userRemote.name;
debug('whoami: response %o', username);
reply.code(fastify.statusCode.OK);
return { username };
});
}
export default whoamiRoute;

View File

@@ -1,7 +1,8 @@
import fp from 'fastify-plugin';
import { Config as IConfig } from '@verdaccio/types';
import { Auth, IAuth } from '@verdaccio/auth';
import { FastifyInstance } from 'fastify';
import fp from 'fastify-plugin';
import { Auth, IAuth } from '@verdaccio/auth';
import { Config as IConfig } from '@verdaccio/types';
export default fp(
async function (fastify: FastifyInstance, opts: { config: IConfig; filters?: unknown }) {

View File

@@ -1,8 +1,8 @@
import { FastifyInstance } from 'fastify';
import fp from 'fastify-plugin';
import { Config as IConfig, ConfigRuntime } from '@verdaccio/types';
import { Config as AppConfig } from '@verdaccio/config';
import { FastifyInstance } from 'fastify';
import { ConfigRuntime, Config as IConfig } from '@verdaccio/types';
export default fp(
async function (fastify: FastifyInstance, opts: { config: ConfigRuntime }) {

View File

@@ -1,11 +1,19 @@
import fp from 'fastify-plugin';
import { errorUtils, validatioUtils, API_ERROR, API_MESSAGE, HTTP_STATUS } from '@verdaccio/core';
import {
API_ERROR,
API_MESSAGE,
HTTP_STATUS,
constants,
errorUtils,
validatioUtils,
} from '@verdaccio/core';
export default fp(
async function (fastify) {
fastify.decorate('errorUtils', errorUtils);
fastify.decorate('apiError', API_ERROR);
fastify.decorate('constants', constants);
fastify.decorate('apiMessage', API_MESSAGE);
fastify.decorate('validatioUtils', validatioUtils);
fastify.decorate('statusCode', HTTP_STATUS);
@@ -19,7 +27,8 @@ declare module 'fastify' {
interface FastifyInstance {
apiError: typeof API_ERROR;
apiMessage: typeof API_MESSAGE;
httpStatuscode: typeof HTTP_STATUS;
statusCode: typeof HTTP_STATUS;
errorUtils: typeof errorUtils;
constants: typeof constants;
}
}

View File

@@ -1,7 +1,8 @@
import fp from 'fastify-plugin';
import { Config as IConfig } from '@verdaccio/types';
import { Storage } from '@verdaccio/store';
import { FastifyInstance } from 'fastify';
import fp from 'fastify-plugin';
import { Storage } from '@verdaccio/store';
import { Config as IConfig } from '@verdaccio/types';
export default fp(
async function (fastify: FastifyInstance, opts: { config: IConfig; filters?: unknown }) {

View File

@@ -0,0 +1,75 @@
import buildDebug from 'debug';
import { FastifyInstance } from 'fastify';
import _ from 'lodash';
import { JWTSignOptions } from '@verdaccio/types';
import { validatePassword } from '@verdaccio/utils';
const debug = buildDebug('verdaccio:api:login');
async function loginRoute(fastify: FastifyInstance) {
fastify.post('/login', async (request, reply) => {
// @ts-expect-error
const { username, password } = request.body;
debug('authenticate %o', username);
fastify.auth.authenticate(
username,
password,
async function callbackAuthenticate(err, user): Promise<void> {
if (err) {
const errorCode = err.message
? fastify.statusCode.UNAUTHORIZED
: fastify.statusCode.INTERNAL_ERROR;
reply.send(fastify.errorUtils.getCode(errorCode, err.message));
} else {
const jWTSignOptions: JWTSignOptions = fastify.configInstance.security.web.sign;
debug('jwtSignOptions: %o', jWTSignOptions);
const token = await fastify.auth.jwtEncrypt(user, jWTSignOptions);
reply.code(fastify.statusCode.OK).send({ token, username });
}
}
);
});
fastify.put('/reset_password', async (request, reply) => {
if (_.isNil(request.userRemote.name)) {
reply.send(
fastify.errorUtils.getCode(
fastify.statusCode.UNAUTHORIZED,
fastify.errorUtils.API_ERROR.MUST_BE_LOGGED
)
);
}
// @ts-ignore
const { password } = request.body;
const { name } = request.userRemote;
if (validatePassword(password.new) === false) {
fastify.auth.changePassword(
name as string,
password.old,
password.new,
(err, isUpdated): void => {
if (_.isNil(err) && isUpdated) {
reply.code(fastify.statusCode.OK);
} else {
reply.send(
fastify.errorUtils.getInternalError(
fastify.errorUtils.API_ERROR.INTERNAL_SERVER_ERROR
)
);
}
}
);
} else {
reply.send(
fastify.errorUtils.getCode(
fastify.statusCode.BAD_REQUEST,
fastify.errorUtils.APP_ERROR.PASSWORD_VALIDATION
)
);
}
});
// });
}
export default loginRoute;

View File

@@ -0,0 +1,75 @@
import buildDebug from 'debug';
import { FastifyInstance } from 'fastify';
import _ from 'lodash';
import sanitizyReadme from '@verdaccio/readme';
const debug = buildDebug('verdaccio:api:whoami');
export const NOT_README_FOUND = 'ERROR: No README data found!';
function getReadme(fastify: FastifyInstance, request: any, packageName, callback) {
fastify.storage.getPackage({
name: packageName,
uplinksLook: true,
req: request.raw,
callback: function (err, readme): void {
debug('readme pkg %o', readme?.name);
if (err) {
callback(err);
return;
}
try {
const parsedReadme = parseReadme(readme.name, readme.readme);
callback(null, parsedReadme);
} catch {
callback(fastify.statusCode.NOT_FOUND).send(err);
}
},
});
}
async function readmeRoute(fastify: FastifyInstance) {
fastify.get('/package/readme/:packageName', async (request, reply) => {
// @ts-ignore
const { version, packageName } = request.params;
debug('readme name %s version: %s', packageName, version);
getReadme(fastify, request, packageName, (err, readme) => {
if (err) {
reply.send(err);
} else {
reply.code(fastify.statusCode.OK).send(readme);
}
});
});
fastify.get('/package/readme/:scope/:packageName', async (request, reply) => {
// @ts-ignore
const { scope, packageName } = request.params;
const packageNameScope = scope ? `${scope}/${packageName}` : packageName;
debug('readme name %s', packageName);
debug('readme endpoint scope:%s pkg: %s', scope, packageName);
getReadme(fastify, request, packageNameScope, (err, readme) => {
if (err) {
reply.send(err);
} else {
reply.code(fastify.statusCode.OK).send(readme);
}
});
});
}
export default readmeRoute;
/**
* parse package readme - markdown/ascii
* @param {String} packageName name of package
* @param {String} readme package readme
* @return {String} converted html template
*/
export function parseReadme(packageName: string, readme: string): string | void {
if (_.isEmpty(readme) === false) {
debug('sanizity readme');
return sanitizyReadme(readme);
}
throw new Error('ERROR: No README data found!');
}

View File

@@ -0,0 +1,68 @@
import buildDebug from 'debug';
import { FastifyInstance } from 'fastify';
import _ from 'lodash';
import { DIST_TAGS } from '@verdaccio/core';
import { convertDistRemoteToLocalTarballUrls } from '@verdaccio/tarball';
import { Package, Version } from '@verdaccio/types';
import {
addGravatarSupport,
deleteProperties,
formatAuthor,
isVersionValid,
} from '@verdaccio/utils';
const debug = buildDebug('verdaccio:web:api:sidebar');
export type $SidebarPackage = Package & { latest: Version };
async function sidebarRoute(fastify: FastifyInstance) {
fastify.get('/sidebar/(@:scope/)?:packageName', async (request, reply) => {
// @ts-ignore
const { packageName, scope } = request.params;
debug('pkg name %s, scope %s ', packageName, scope);
getSidebar(fastify, request, packageName, (err, sidebar) => {
if (err) {
reply.send(err);
} else {
reply.code(fastify.statusCode.OK).send(sidebar);
}
});
});
}
function getSidebar(fastify: FastifyInstance, request: any, packageName, callback) {
fastify.storage.getPackage({
name: packageName,
uplinksLook: true,
keepUpLinkData: true,
req: request.raw,
callback: function (err: Error, info: $SidebarPackage): void {
debug('sidebar pkg info %o', info);
if (_.isNil(err)) {
const { v } = request.query;
let sideBarInfo = _.clone(info);
sideBarInfo.versions = convertDistRemoteToLocalTarballUrls(
info,
{ protocol: request.protocol, headers: request.headers as any, host: request.hostname },
fastify.configInstance.url_prefix
).versions;
if (typeof v === 'string' && isVersionValid(info, v)) {
sideBarInfo.latest = sideBarInfo.versions[v];
sideBarInfo.latest.author = formatAuthor(sideBarInfo.latest.author);
} else {
sideBarInfo.latest = sideBarInfo.versions[info[DIST_TAGS].latest];
sideBarInfo.latest.author = formatAuthor(sideBarInfo.latest.author);
}
sideBarInfo = deleteProperties(['readme', '_attachments', '_rev', 'name'], sideBarInfo);
const authorAvatar = fastify.configInstance.web
? addGravatarSupport(sideBarInfo, fastify.configInstance.web.gravatar)
: addGravatarSupport(sideBarInfo);
callback(null, authorAvatar);
} else {
callback(fastify.statusCode.NOT_FOUND).send(err);
}
},
});
}
export default sidebarRoute;

View File

@@ -1,16 +1,22 @@
import { Config as IConfig, RemoteUser } from '@verdaccio/types';
import { Config as AppConfig, createAnonymousRemoteUser } from '@verdaccio/config';
import fastify from 'fastify';
import buildDebug from 'debug';
import fastify from 'fastify';
import search from './endpoints/search';
import storagePlugin from './plugins/storage';
import authPlugin from './plugins/auth';
import coreUtils from './plugins/coreUtils';
import configPlugin from './plugins/config';
import { Config as AppConfig, createAnonymousRemoteUser } from '@verdaccio/config';
import { Config as IConfig, RemoteUser } from '@verdaccio/types';
import distTags from './endpoints/dist-tags';
import ping from './endpoints/ping';
import search from './endpoints/search';
import tarball from './endpoints/tarball';
import user from './endpoints/user';
import whoami from './endpoints/whoami';
import authPlugin from './plugins/auth';
import configPlugin from './plugins/config';
import coreUtils from './plugins/coreUtils';
import storagePlugin from './plugins/storage';
import login from './routes/web/api/login';
import readme from './routes/web/api/readme';
import sidebar from './routes/web/api/sidebar';
const debug = buildDebug('verdaccio:fastify');
@@ -20,16 +26,23 @@ async function startServer({ logger, config }) {
debug('start server');
const fastifyInstance = fastify({ logger });
fastifyInstance.decorateRequest<RemoteUser>('userRemote', createAnonymousRemoteUser());
fastifyInstance.register(configPlugin, { config });
fastifyInstance.register(coreUtils);
fastifyInstance.register(authPlugin, { config: configInstance });
fastifyInstance.register(configPlugin, { config });
fastifyInstance.register(storagePlugin, { config: configInstance });
fastifyInstance.register(authPlugin, { config: configInstance });
// api
fastifyInstance.register((instance, opts, done) => {
instance.register(ping);
instance.register(user, { prefix: '/-/user' });
instance.register(search);
instance.register(whoami);
instance.register(tarball);
instance.register(distTags);
instance.register(readme, { prefix: '/-/verdaccio' });
instance.register(sidebar, { prefix: '/-/verdaccio' });
instance.register(login, { prefix: '/-/verdaccio' });
done();
});

View File

@@ -1,5 +1,12 @@
# Change Log
## 11.0.0-6-next.10
### Patch Changes
- Updated dependencies [f86c31ed]
- @verdaccio/utils@6.0.0-6-next.9
## 11.0.0-6-next.9
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/tarball",
"version": "11.0.0-6-next.9",
"version": "11.0.0-6-next.10",
"description": "tarball utilities resolver",
"keywords": [
"private",
@@ -36,12 +36,11 @@
"dependencies": {
"@verdaccio/core": "workspace:6.0.0-6-next.3",
"@verdaccio/url": "workspace:11.0.0-6-next.7",
"@verdaccio/utils": "workspace:6.0.0-6-next.8",
"@verdaccio/utils": "workspace:6.0.0-6-next.9",
"lodash": "4.17.21"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-6-next.9",
"express": "4.17.1",
"node-mocks-http": "1.10.1"
},
"scripts": {

View File

@@ -1,7 +1,8 @@
import { Package } from '@verdaccio/types';
import { Request } from 'express';
import _ from 'lodash';
import { Package } from '@verdaccio/types';
import { RequestOptions } from '@verdaccio/url';
import { getLocalRegistryTarballUri } from './getLocalRegistryTarballUri';
/**
@@ -13,7 +14,7 @@ import { getLocalRegistryTarballUri } from './getLocalRegistryTarballUri';
*/
export function convertDistRemoteToLocalTarballUrls(
pkg: Package,
req: Request,
request: RequestOptions,
urlPrefix: string | void
): Package {
for (const ver in pkg.versions) {
@@ -21,7 +22,12 @@ export function convertDistRemoteToLocalTarballUrls(
const distName = pkg.versions[ver].dist;
if (_.isNull(distName) === false && _.isNull(distName.tarball) === false) {
distName.tarball = getLocalRegistryTarballUri(distName.tarball, pkg.name, req, urlPrefix);
distName.tarball = getLocalRegistryTarballUri(
distName.tarball,
pkg.name,
request,
urlPrefix
);
}
}
}

View File

@@ -1,12 +1,12 @@
import URL from 'url';
import { Request } from 'express';
import buildDebug from 'debug';
import URL from 'url';
import { RequestOptions } from '@verdaccio/url';
import { getPublicUrl } from '@verdaccio/url';
const debug = buildDebug('verdaccio:core:url');
function extractTarballFromUrl(url: string): string {
export function extractTarballFromUrl(url: string): string {
// @ts-ignore
return URL.parse(url).pathname.replace(/^.*\//, '');
}
@@ -18,10 +18,10 @@ function extractTarballFromUrl(url: string): string {
export function getLocalRegistryTarballUri(
uri: string,
pkgName: string,
req: Request,
requestOptions: RequestOptions,
urlPrefix: string | void
): string {
const currentHost = req.headers.host;
const currentHost = requestOptions?.headers?.host;
if (!currentHost) {
return uri;
@@ -29,7 +29,7 @@ export function getLocalRegistryTarballUri(
const tarballName = extractTarballFromUrl(uri);
debug('tarball name %o', tarballName);
// header only set with proxy that setup with HTTPS
const domainRegistry = getPublicUrl(urlPrefix || '', req);
const domainRegistry = getPublicUrl(urlPrefix || '', requestOptions);
return `${domainRegistry}${pkgName}/-/${tarballName}`;
}

View File

@@ -1,5 +1,7 @@
import * as httpMocks from 'node-mocks-http';
import { HEADERS } from '@verdaccio/core';
import { convertDistRemoteToLocalTarballUrls } from '../src';
describe('convertDistRemoteToLocalTarballUrls', () => {
@@ -30,7 +32,11 @@ describe('convertDistRemoteToLocalTarballUrls', () => {
},
url: '/',
});
const convertDist = convertDistRemoteToLocalTarballUrls(cloneMetadata(), req);
const convertDist = convertDistRemoteToLocalTarballUrls(cloneMetadata(), {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
});
expect(convertDist.versions['1.0.0'].dist.tarball).toEqual(buildURI(fakeHost, '1.0.0'));
expect(convertDist.versions['1.0.1'].dist.tarball).toEqual(buildURI(fakeHost, '1.0.1'));
});
@@ -43,7 +49,11 @@ describe('convertDistRemoteToLocalTarballUrls', () => {
},
url: '/',
});
const convertDist = convertDistRemoteToLocalTarballUrls(cloneMetadata(), req);
const convertDist = convertDistRemoteToLocalTarballUrls(cloneMetadata(), {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
});
expect(convertDist.versions['1.0.0'].dist.tarball).toEqual(
convertDist.versions['1.0.0'].dist.tarball
);
@@ -57,7 +67,11 @@ describe('convertDistRemoteToLocalTarballUrls', () => {
},
url: '/',
});
const convertDist = convertDistRemoteToLocalTarballUrls(cloneMetadata(), req);
const convertDist = convertDistRemoteToLocalTarballUrls(cloneMetadata(), {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
});
expect(convertDist.versions['1.0.0'].dist.tarball).toEqual(
convertDist.versions['1.0.0'].dist.tarball
);

View File

@@ -12,6 +12,9 @@
},
{
"path": "../url"
},
{
"path": "../core"
}
]
}

View File

@@ -1,6 +1,6 @@
/// <reference types="node" />
import { PassThrough } from 'stream';
declare module '@verdaccio/types' {
type StringValue = string | void | null;

View File

@@ -1,6 +1,7 @@
import { URL } from 'url';
import buildDebug from 'debug';
import { URL } from 'url';
import isURLValidator from 'validator/lib/isURL';
import { HEADERS } from '@verdaccio/core';
const debug = buildDebug('verdaccio:core:url');
@@ -88,18 +89,26 @@ export function validateURL(publicUrl: string | void) {
}
}
export function getPublicUrl(url_prefix: string = '', req): string {
export type RequestOptions = {
host: string;
protocol: string;
headers: { [key: string]: string };
};
export function getPublicUrl(url_prefix: string = '', requestOptions: RequestOptions): string {
if (validateURL(process.env.VERDACCIO_PUBLIC_URL as string)) {
const envURL = new URL(wrapPrefix(url_prefix), process.env.VERDACCIO_PUBLIC_URL as string).href;
debug('public url by env %o', envURL);
return envURL;
} else if (req.get('host')) {
const host = req.get('host');
} else if (requestOptions.headers['host']) {
const host = requestOptions.headers['host'];
if (!isHost(host)) {
throw new Error('invalid host');
}
const protoHeader = process.env.VERDACCIO_FORWARDED_PROTO ?? HEADERS.FORWARDED_PROTO;
const protocol = getWebProtocol(req.get(protoHeader), req.protocol);
const protoHeader =
process.env.VERDACCIO_FORWARDED_PROTO?.toLocaleLowerCase() ??
HEADERS.FORWARDED_PROTO.toLowerCase();
const protocol = getWebProtocol(requestOptions.headers[protoHeader], requestOptions.protocol);
const combinedUrl = combineBaseUrl(protocol, host, url_prefix);
debug('public url by request %o', combinedUrl);
return combinedUrl;

View File

@@ -1,6 +1,7 @@
import * as httpMocks from 'node-mocks-http';
import { HEADERS } from '@verdaccio/core';
import { getPublicUrl } from '../src';
describe('host', () => {
@@ -11,7 +12,13 @@ describe('host', () => {
method: 'GET',
url: '/',
});
expect(getPublicUrl(undefined, req)).toEqual('/');
expect(
getPublicUrl(undefined, {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
})
).toEqual('/');
});
test('get a valid host', () => {
@@ -22,7 +29,13 @@ describe('host', () => {
},
url: '/',
});
expect(getPublicUrl(undefined, req)).toEqual('http://some.com/');
expect(
getPublicUrl(undefined, {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
})
).toEqual('http://some.com/');
});
test('check a valid host header injection', () => {
@@ -31,11 +44,15 @@ describe('host', () => {
headers: {
host: `some.com"><svg onload="alert(1)">`,
},
hostname: `some.com"><svg onload="alert(1)">`,
url: '/',
});
expect(function () {
// @ts-expect-error
getPublicUrl({}, req);
getPublicUrl('', {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
});
}).toThrow('invalid host');
});
@@ -48,7 +65,13 @@ describe('host', () => {
url: '/',
});
expect(getPublicUrl('/prefix/', req)).toEqual('http://some.com/prefix/');
expect(
getPublicUrl('/prefix/', {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
})
).toEqual('http://some.com/prefix/');
});
test('get a valid host with prefix no trailing', () => {
@@ -60,7 +83,13 @@ describe('host', () => {
url: '/',
});
expect(getPublicUrl('/prefix-no-trailing', req)).toEqual('http://some.com/prefix-no-trailing/');
expect(
getPublicUrl('/prefix-no-trailing', {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
})
).toEqual('http://some.com/prefix-no-trailing/');
});
test('get a valid host with null prefix', () => {
@@ -72,7 +101,13 @@ describe('host', () => {
url: '/',
});
expect(getPublicUrl(null, req)).toEqual('http://some.com/');
expect(
getPublicUrl(null, {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
})
).toEqual('http://some.com/');
});
});
@@ -87,7 +122,13 @@ describe('X-Forwarded-Proto', () => {
url: '/',
});
expect(getPublicUrl(undefined, req)).toEqual('https://some.com/');
expect(
getPublicUrl(undefined, {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
})
).toEqual('https://some.com/');
});
test('with a invalid X-Forwarded-Proto https', () => {
@@ -100,7 +141,13 @@ describe('X-Forwarded-Proto', () => {
url: '/',
});
expect(getPublicUrl(undefined, req)).toEqual('http://some.com/');
expect(
getPublicUrl(undefined, {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
})
).toEqual('http://some.com/');
});
test('with a HAProxy X-Forwarded-Proto https', () => {
@@ -113,7 +160,13 @@ describe('X-Forwarded-Proto', () => {
url: '/',
});
expect(getPublicUrl(undefined, req)).toEqual('https://some.com/');
expect(
getPublicUrl(undefined, {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
})
).toEqual('https://some.com/');
});
test('with a HAProxy X-Forwarded-Proto different protocol', () => {
@@ -126,7 +179,13 @@ describe('X-Forwarded-Proto', () => {
url: '/',
});
expect(getPublicUrl(undefined, req)).toEqual('http://some.com/');
expect(
getPublicUrl(undefined, {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
})
).toEqual('http://some.com/');
});
});
@@ -142,7 +201,13 @@ describe('env variable', () => {
url: '/',
});
expect(getPublicUrl(undefined, req)).toEqual('https://env.domain.com/');
expect(
getPublicUrl(undefined, {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
})
).toEqual('https://env.domain.com/');
delete process.env.VERDACCIO_PUBLIC_URL;
});
@@ -157,7 +222,13 @@ describe('env variable', () => {
url: '/',
});
expect(getPublicUrl(undefined, req)).toEqual('https://env.domain.com/urlPrefix/');
expect(
getPublicUrl(undefined, {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
})
).toEqual('https://env.domain.com/urlPrefix/');
delete process.env.VERDACCIO_PUBLIC_URL;
});
@@ -172,7 +243,13 @@ describe('env variable', () => {
url: '/',
});
expect(getPublicUrl(undefined, req)).toEqual('https://env.domain.com/');
expect(
getPublicUrl(undefined, {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
})
).toEqual('https://env.domain.com/');
delete process.env.VERDACCIO_PUBLIC_URL;
});
@@ -187,7 +264,13 @@ describe('env variable', () => {
url: '/',
});
expect(getPublicUrl(undefined, req)).toEqual('http://some.com/');
expect(
getPublicUrl(undefined, {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
})
).toEqual('http://some.com/');
delete process.env.VERDACCIO_PUBLIC_URL;
});
@@ -202,7 +285,13 @@ describe('env variable', () => {
url: '/',
});
expect(getPublicUrl(undefined, req)).toEqual('http://some.com/');
expect(
getPublicUrl(undefined, {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
})
).toEqual('http://some.com/');
delete process.env.VERDACCIO_PUBLIC_URL;
});
@@ -217,7 +306,13 @@ describe('env variable', () => {
url: '/',
});
expect(getPublicUrl(undefined, req)).toEqual('http://some/');
expect(
getPublicUrl(undefined, {
host: req.hostname,
headers: req.headers as any,
protocol: req.protocol,
})
).toEqual('http://some/');
delete process.env.VERDACCIO_PUBLIC_URL;
});
});

View File

@@ -39,9 +39,9 @@
"undici-fetch": "1.0.0-rc.4"
},
"devDependencies": {
"@types/node": "16.9.1",
"@verdaccio/auth": "workspace:6.0.0-6-next.14",
"@verdaccio/config": "workspace:6.0.0-6-next.10",
"@types/node": "16.11.6",
"@verdaccio/auth": "workspace:6.0.0-6-next.15",
"@verdaccio/config": "workspace:6.0.0-6-next.11",
"@verdaccio/types": "workspace:11.0.0-6-next.9"
},
"scripts": {

View File

@@ -1,7 +1,7 @@
import buildDebug from 'debug';
import { logger } from '@verdaccio/logger';
import { HTTP_STATUS } from '@verdaccio/core';
import { logger } from '@verdaccio/logger';
const debug = buildDebug('verdaccio:hooks:request');
const fetch = require('undici-fetch');

View File

@@ -1,11 +1,11 @@
/* eslint-disable no-undef */
import buildDebug from 'debug';
import Handlebars from 'handlebars';
import buildDebug from 'debug';
import { Config, Package, RemoteUser, Notification } from '@verdaccio/types';
import { logger } from '@verdaccio/logger';
import { notifyRequest, FetchOptions } from './notify-request';
import { Config, Notification, Package, RemoteUser } from '@verdaccio/types';
import { FetchOptions, notifyRequest } from './notify-request';
const debug = buildDebug('verdaccio:hooks');

View File

@@ -1,6 +1,7 @@
import { createRemoteUser, parseConfigFile } from '@verdaccio/config';
import { setup } from '@verdaccio/logger';
import { Config } from '@verdaccio/types';
import { parseConfigFile, createRemoteUser } from '@verdaccio/config';
import { notify } from '../src/notify';
import { parseConfigurationFile } from './__helper';

Some files were not shown because too many files have changed in this diff Show More