0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2025-04-08 02:54:13 -05:00

fix: eslint errors (#1973)

* fix: eslint errors

* fix: rename a test

* fix: broken integration test

due to removing next argument in the middleware.

* changeset
This commit is contained in:
Dina Basumatary 2020-10-24 22:17:21 +11:00 committed by GitHub
parent a4667f3440
commit 31af01641f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
53 changed files with 389 additions and 243 deletions

View file

@ -0,0 +1,34 @@
---
'@verdaccio/api': patch
'@verdaccio/auth': patch
'@verdaccio/cli': patch
'@verdaccio/dev-commons': patch
'@verdaccio/config': patch
'@verdaccio/commons-api': patch
'@verdaccio/file-locking': patch
'@verdaccio/htpasswd': patch
'@verdaccio/local-storage': patch
'@verdaccio/readme': patch
'@verdaccio/types': patch
'@verdaccio/hooks': patch
'@verdaccio/loaders': patch
'@verdaccio/logger': patch
'@verdaccio/logger-prettify': patch
'@verdaccio/middleware': patch
'@verdaccio/mock': patch
'@verdaccio/node-api': patch
'@verdaccio/proxy': patch
'@verdaccio/server': patch
'@verdaccio/store': patch
'@verdaccio/dev-types': patch
'@verdaccio/utils': patch
'verdaccio': patch
---
ESLint Warnings Fixed
Related to issue #1461
- max-len: most of the sensible max-len errors are fixed
- no-unused-vars: most of these types of errors are fixed by deleting not needed declarations
- @typescript-eslint/no-unused-vars: same as above

View file

@ -57,31 +57,36 @@ export default function publish(
*
* Unpublish consist in 3 steps.
* 1. Try to fetch metadata -> if it fails, return 404
* 2. Compute metadata locally (client side) and send a mutate payload excluding the version to be unpublished
* 2. Compute metadata locally (client side) and send a mutate payload excluding the version to
* be unpublished
* eg: if metadata reflects 1.0.1, 1.0.2 and 1.0.3, the computed metadata won't include 1.0.3.
* 3. Once the second step has been successfully finished, delete the tarball.
*
* All these steps are consecutive and required, there is no transacions here, if step 3 fails, metadata might
* get corrupted.
* All these steps are consecutive and required, there is no transacions here, if step 3 fails,
* metadata might get corrupted.
*
* Note the unpublish call will suffix in the url a /-rev/14-5d500cfce92f90fd revision number, this not
* Note the unpublish call will suffix in the url a /-rev/14-5d500cfce92f90fd revision number,
* this not
* used internally.
*
*
* Example flow of unpublish.
*
* npm http fetch GET 200 http://localhost:4873/@scope%2ftest1?write=true 1680ms
npm http fetch PUT 201 http://localhost:4873/@scope%2ftest1/-rev/14-5d500cfce92f90fd 956606ms attempt #2
npm http fetch GET 200 http://localhost:4873/@scope%2ftest1?write=true 1601ms
npm http fetch DELETE 201 http://localhost:4873/@scope%2ftest1/-/test1-1.0.3.tgz/-rev/16-e11c8db282b2d992 19ms
* npm http fetch PUT 201 http://localhost:4873/@scope%2ftest1/-rev/14-5d500cfce92f90fd
* 956606ms attempt #2
* npm http fetch GET 200 http://localhost:4873/@scope%2ftest1?write=true 1601ms
* npm http fetch DELETE 201 http://localhost:4873/@scope%2ftest1/-/test1-1.0.3.tgz/-rev/16
* -e11c8db282b2d992 19ms
*
* 3. Star a package
*
* Permissions: start a package depends of the publish and unpublish permissions, there is no specific flag for star or un start.
* Permissions: start a package depends of the publish and unpublish permissions, there is no
* specific flag for star or un start.
* The URL for star is similar to the unpublish (change package format)
*
* npm has no enpoint for star a package, rather mutate the metadata and acts as, the difference is the
* users property which is part of the payload and the body only includes
* npm has no enpoint for star a package, rather mutate the metadata and acts as, the difference
* is the users property which is part of the payload and the body only includes
*
* {
"_id": pkgName,
@ -209,9 +214,12 @@ export function publishPackage(storage: IStorageHandler, config: Config, auth: I
});
}
// npm-registry-client 0.3+ embeds tarball into the json upload
// https://github.com/isaacs/npm-registry-client/commit/e9fbeb8b67f249394f735c74ef11fe4720d46ca0
// issue https://github.com/rlidwka/sinopia/issues/31, dealing with it here:
/**
* npm-registry-client 0.3+ embeds tarball into the json upload
* https://github.com/isaacs/npm-registry-client/commit/e9fbeb8b67f249394f735c74ef11fe4720d46ca0
* issue https://github.com/rlidwka/sinopia/issues/31, dealing with it here:
*/
const isInvalidBodyFormat =
isObject(_attachments) === false ||
hasDiffOneKey(_attachments) ||

View file

@ -4,7 +4,7 @@ import _ from 'lodash';
import buildDebug from 'debug';
import { IStorageHandler } from '@verdaccio/store';
import { $RequestExtend, $ResponseExtend, $NextFunctionVer } from '../types/custom';
import { $RequestExtend, $NextFunctionVer } from '../types/custom';
const debug = buildDebug('verdaccio:api:publish:star');

View file

@ -39,7 +39,8 @@ function compileTextSearch(textSearch: string): (pkg: Package) => boolean {
export default function (route, auth, storage): void {
route.get('/-/v1/search', (req, res) => {
// TODO: implement proper result scoring weighted by quality, popularity and maintenance query parameters
// TODO: implement proper result scoring weighted by quality, popularity and
// maintenance query parameters
let [text, size, from /* , quality, popularity, maintenance */] = [
'text',
'size',

View file

@ -96,7 +96,8 @@ export default function (
/**
* cidr_whitelist: is not being used, we pass it through
* token: we do not store the real token (it is generated once and retrieved to the user), just a mask of it.
* token: we do not store the real token (it is generated once and retrieved
* to the user), just a mask of it.
*/
const saveToken: Token = {
user: name,

View file

@ -162,7 +162,6 @@ class Auth implements IAuth {
public authenticate(username: string, password: string, cb: Callback): void {
const plugins = this.plugins.slice(0);
const self = this;
(function next(): void {
const plugin = plugins.shift() as IPluginAuth<Config>;
@ -213,7 +212,8 @@ class Auth implements IAuth {
if (isFunction(plugin[method]) === false) {
method = 'add_user';
self.logger.warn(
'the plugin method add_user in the auth plugin is deprecated and will be removed in next major release, notify to the plugin author'
'the plugin method add_user in the auth plugin is deprecated and will' +
' be removed in next major release, notify to the plugin author'
);
}
@ -326,7 +326,6 @@ class Auth implements IAuth {
callback: Callback
): void {
const plugins = this.plugins.slice(0);
const self = this;
const pkg = Object.assign(
{ name: packageName, version: packageVersion },
getMatchedPackagesSpec(packageName, this.config.packages)

View file

@ -31,7 +31,6 @@ import {
aesDecrypt,
verifyPayload,
signPayload,
buildUser,
} from '../src';
setup([]);
@ -428,7 +427,7 @@ describe('Auth utilities', () => {
);
});
test('should fail on verify the token and return anonymous users', async () => {
test('should verify the token and return a remote user', async () => {
const remoteUser = createRemoteUser('foo', []);
const token = await signPayload(remoteUser, '12345');
const verifiedToken = verifyJWTPayload(token, '12345');

View file

@ -4,11 +4,11 @@
import commander from 'commander';
import { bgYellow, bgRed } from 'kleur';
import { setup, logger } from '@verdaccio/logger';
import { logger } from '@verdaccio/logger';
import infoCommand from './commands/info';
import initProgram from './commands/init';
import { isVersionValid, MIN_NODE_VERSION } from './utils';
import { isVersionValid } from './utils';
const isRootUser = process.getuid && process.getuid() === 0;
@ -23,7 +23,8 @@ if (isRootUser) {
if (isVersionValid()) {
global.console.error(
bgRed(
`Verdaccio requires at least Node.js ${MIN_NODE_VERSION} or higher, please upgrade your Node.js distribution`
'Verdaccio requires at least Node.js ${MIN_NODE_VERSION} or higher,' +
' please upgrade your Node.js distribution'
)
);
process.exit(1);
@ -61,7 +62,8 @@ process.on('uncaughtException', function (err) {
{
err: err,
},
'uncaught exception, please report (https://github.com/verdaccio/verdaccio/issues) this: \n@{err.stack}'
'uncaught exception, please report (https://github.com/verdaccio/verdaccio/issues) ' +
'this: \n@{err.stack}'
);
process.exit(255);
});

View file

@ -3,7 +3,6 @@ import _ from 'lodash';
import { parseConfigFile } from '@verdaccio/utils';
import { findConfigFile } from '@verdaccio/config';
import { logger, createLogger } from '@verdaccio/logger';
import { startVerdaccio, listenDefaultCallback } from '@verdaccio/node-api';
export const DEFAULT_PROCESS_NAME: string = 'verdaccio';
@ -21,7 +20,8 @@ export default function initProgram(commander, pkgVersion, pkgName) {
process.title = web?.title || DEFAULT_PROCESS_NAME;
// note: self_path is only being used by @verdaccio/storage , not really useful and migth be removed soon
// note: self_path is only being used by @verdaccio/storage, not really useful
// and migth be removed soon
if (!self_path) {
verdaccioConfiguration = _.assign({}, verdaccioConfiguration, {
self_path: path.resolve(configPathLocation),
@ -45,7 +45,6 @@ export default function initProgram(commander, pkgVersion, pkgName) {
listenDefaultCallback
);
} catch (err) {
// initLogger.fatal({file: configPathLocation, err: err}, 'cannot open config file @{file}: @{!err.message}');
process.exit(1);
}
}

View file

@ -106,7 +106,8 @@ export const SUPPORT_ERRORS = {
export const API_ERROR = {
PASSWORD_SHORT: (passLength: number = DEFAULT_MIN_LIMIT_PASSWORD) =>
`The provided password is too short. Please pick a password longer than ${passLength} characters.`,
`The provided password is too short. Please pick a password` +
` longer than ${passLength} characters.`,
MUST_BE_LOGGED: 'You must be logged in to publish packages.',
PLUGIN_ERROR: 'bug in the auth plugin system',
CONFIG_BAD_FORMAT: 'config file must be an object',

View file

@ -43,7 +43,8 @@ export function generatePackageMetadata(
},
dist: {
integrity:
'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr9cmE6dUBf+XoPoH4g==',
'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr9cm' +
'E6dUBf+XoPoH4g==',
shasum: '2c03764f651a9f016ca0b7620421457b619151b9', // pragma: allowlist secret
tarball: `http:\/\/localhost:5555\/${pkgName}\/-\/${pkgName}-${version}.tgz`,
},
@ -54,7 +55,15 @@ export function generatePackageMetadata(
[`${pkgName}-${version}.tgz`]: {
content_type: 'application/octet-stream',
data:
'H4sIAAAAAAAAE+2W32vbMBDH85y/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo//79KPeQsnIw5KUDX/9IOvurLuz/DHSjK/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1aW8eML+Vv10m9oF/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0ScCdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yoEHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS/pLQe+D+FIv/agIWI6GX66kFuIhT+1gDjrp/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0/jWiAK8OcMjt8MW3OlfQppcuhhQ6k+2OgkK2Q8DssFPi/IHpU9fz3/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6/f88f/Pu47zomiPk2Lv/dOv8h+P/34/D/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=+2W32vbMBDH85y',
'H4sIAAAAAAAAE+2W32vbMBDH85y/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo//79KPeQsnI' +
'w5KUDX/9IOvurLuz/DHSjK/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1a' +
'W8eML+Vv10m9oF/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0Sc' +
'CdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y' +
'7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yo' +
'EHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS/pLQe+D+FIv/agIWI6GX66kFuIhT+' +
'1gDjrp/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0/jWiAK8OcMjt8MW3OlfQppcuhhQ6k' +
'+2OgkK2Q8DssFPi/IHpU9fz3/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6/f88f/Pu47zomiPk2Lv/dOv8' +
'h+P/34/D/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=+2W32vbMBDH85y',
length: 512,
},
},

View file

@ -74,8 +74,9 @@ function updateStorageLinks(configLocation, defaultConfig): string {
return defaultConfig;
}
// $XDG_DATA_HOME defines the base directory relative to which user specific data files should be stored,
// If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used.
// $XDG_DATA_HOME defines the base directory relative to which user specific data
// files should be stored, If $XDG_DATA_HOME is either not set or empty, a default
// equal to $HOME/.local/share should be used.
// $FlowFixMe
let dataDir =
process.env.XDG_DATA_HOME || Path.join(process.env.HOME as string, '.local', 'share');

View file

@ -5,7 +5,7 @@ import { setup } from '@verdaccio/logger';
import { DEFAULT_REGISTRY, DEFAULT_UPLINK, ROLES, WEB_TITLE } from '@verdaccio/dev-commons';
import { parseConfigFile } from '@verdaccio/utils';
import { Config, readDefaultConfig } from '../src';
import { Config } from '../src';
setup([]);
@ -95,6 +95,4 @@ describe('Config file', () => {
checkDefaultConfPackages(config);
});
});
describe('Config file', () => {});
});

View file

@ -58,7 +58,8 @@ export const API_MESSAGE = {
export const API_ERROR = {
PASSWORD_SHORT: (passLength = DEFAULT_MIN_LIMIT_PASSWORD): string =>
`The provided password is too short. Please pick a password longer than ${passLength} characters.`,
`The provided password is too short. Please pick a password longer than ` +
`${passLength} characters.`,
MUST_BE_LOGGED: 'You must be logged in to publish packages.',
PLUGIN_ERROR: 'bug in the auth plugin system',
CONFIG_BAD_FORMAT: 'config file must be an object',

View file

@ -92,7 +92,7 @@ describe('testing locking', () => {
});
});
test('read file with options should to be found to be read it and fails to be parsed', (done) => {
test('read file with options should be found to be read it and fails to be parsed', (done) => {
const options = {
parse: true,
};
@ -102,7 +102,7 @@ describe('testing locking', () => {
});
});
test('read file with options (parse, lock) should to be found to be read it as object', (done) => {
test('read file with options (parse, lock) should be found to be read it as object', (done) => {
const options = {
parse: true,
lock: true,
@ -120,16 +120,19 @@ describe('testing locking', () => {
});
});
test('read file with options (parse, lock) should to be found to be read it and fails to be parsed', (done) => {
const options = {
parse: true,
lock: true,
};
readFile(getFilePath('wrong.package.json'), options, (error: Error) => {
expect(error.message).toMatch(/Unexpected token } in JSON at position \d+/);
removeTempFile('wrong.package.json.lock');
done();
});
});
test(
'read file with options (parse, lock) should be found to be read and ' + 'fails to be parsed',
(done) => {
const options = {
parse: true,
lock: true,
};
readFile(getFilePath('wrong.package.json'), options, (error: Error) => {
expect(error.message).toMatch(/Unexpected token } in JSON at position \d+/);
removeTempFile('wrong.package.json.lock');
done();
});
}
);
});
});

View file

@ -207,13 +207,16 @@ describe('sanityCheck', () => {
expect(verifyFn).toHaveBeenCalledTimes(1);
});
test('should throw error for existing username and password with max number of users reached', () => {
const verifyFn = jest.fn(() => true);
const input = sanityCheck('test', users.test, verifyFn, users, 1);
expect(input.status).toEqual(409);
expect(input.message).toEqual('username is already registered');
expect(verifyFn).toHaveBeenCalledTimes(1);
});
test(
'should throw error for existing username and password with max number ' + 'of users reached',
() => {
const verifyFn = jest.fn(() => true);
const input = sanityCheck('test', users.test, verifyFn, users, 1);
expect(input.status).toEqual(409);
expect(input.message).toEqual('username is already registered');
expect(verifyFn).toHaveBeenCalledTimes(1);
}
);
});
describe('changePasswordToHTPasswd', () => {

View file

@ -340,10 +340,12 @@ class LocalDatabase implements IPluginStorage<{}> {
if (this.locked) {
this.logger.error(
'Database is locked, please check error message printed during startup to prevent data loss.'
'Database is locked, please check error message printed during startup to ' +
'prevent data loss.'
);
return new Error(
'Verdaccio database is locked, please contact your administrator to checkout logs during verdaccio startup.'
'Verdaccio database is locked, please contact your administrator to checkout ' +
'logs during verdaccio startup.'
);
}
// Uses sync to prevent ugly race condition

View file

@ -18,7 +18,8 @@ export function loadPrivatePackages(path: string, logger: Logger): LocalStorage
db = JSON.parse(data);
} catch (err) {
logger.error(
`Package database file corrupted (invalid JSON), please check the error printed below.\nFile Path: ${path}`,
`Package database file corrupted (invalid JSON), please check the error` +
` printed below.\nFile Path: ${path}`,
err
);
throw Error('Package database file corrupted (invalid JSON)');

View file

@ -31,7 +31,8 @@ const json = {
_npmUser: {},
dist: {
integrity:
'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr9cmE6dUBf+XoPoH4g==',
'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr9c' +
'mE6dUBf+XoPoH4g==',
shasum: '2c03764f651a9f016ca0b7620421457b619151b9',
tarball: 'http://localhost:5555/@scope/pk1-test/-/@scope/pk1-test-1.0.6.tgz',
},
@ -42,7 +43,15 @@ const json = {
'@scope/pk1-test-1.0.6.tgz': {
content_type: 'application/octet-stream',
data:
'H4sIAAAAAAAAE+2W32vbMBDH85y/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo//79KPeQsnIw5KUDX/9IOvurLuz/DHSjK/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1aW8eML+Vv10m9oF/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0ScCdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yoEHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS/pLQe+D+FIv/agIWI6GX66kFuIhT+1gDjrp/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0/jWiAK8OcMjt8MW3OlfQppcuhhQ6k+2OgkK2Q8DssFPi/IHpU9fz3/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6/f88f/Pu47zomiPk2Lv/dOv8h+P/34/D/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=',
'H4sIAAAAAAAAE+2W32vbMBDH85y/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo//79KPeQsnI' +
'w5KUDX/9IOvurLuz/DHSjK/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1a' +
'W8eML+Vv10m9oF/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0Sc' +
'CdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y' +
'7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yo' +
'EHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS/pLQe+D+FIv/agIWI6GX66kFuIhT+' +
'1gDjrp/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0/jWiAK8OcMjt8MW3OlfQppcuhhQ6k' +
'+2OgkK2Q8DssFPi/IHpU9fz3/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6/f88f/Pu47zomiPk2Lv/dOv8' +
'h+P/34/D/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=',
length: 512,
},
},

View file

@ -73,7 +73,8 @@ describe('readme', () => {
'![Escape SRC - onload](https://www.example.com/image.png"onload="alert(\'ImageOnLoad\'))'
)
).toEqual(
'<p><img alt="Escape SRC - onload" src="https://www.example.com/image.png%22onload=%22alert(\'ImageOnLoad\')"></p>'
'<p><img alt="Escape SRC - onload" src="https://www.example.com/image.png%22onload=' +
"%22alert('ImageOnLoad')\"></p>"
);
});
@ -104,10 +105,13 @@ describe('readme', () => {
test('xss / data test/html encoded', () => {
expect(
parseReadme(
'[XSS](&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29)'
'[XSS](&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x7' +
'2&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29)'
)
).toEqual(
'<p><a href="&amp;#x6A&amp;#x61&amp;#x76&amp;#x61&amp;#x73&amp;#x63&amp;#x72&amp;#x69&amp;#x70&amp;#x74&amp;#x3A&amp;#x61&amp;#x6C&amp;#x65&amp;#x72&amp;#x74&amp;#x28&amp;#x27&amp;#x58&amp;#x53&amp;#x53&amp;#x27&amp;#x29">XSS</a></p>'
'<p><a href="&amp;#x6A&amp;#x61&amp;#x76&amp;#x61&amp;#x73&amp;#x63&amp;#x72&amp;' +
'#x69&amp;#x70&amp;#x74&amp;#x3A&amp;#x61&amp;#x6C&amp;#x65&amp;#x72&amp;#x74&amp' +
';#x28&amp;#x27&amp;#x58&amp;#x53&amp;#x53&amp;#x27&amp;#x29">XSS</a></p>'
);
});
@ -218,7 +222,8 @@ describe('readme', () => {
expect(
parseReadme('![XSS](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)\\')
).toEqual(
'<p><img alt="XSS" src="data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">\\</p>'
'<p><img alt="XSS" src="data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3Nj' +
'cmlwdD4K">\\</p>'
);
});
@ -236,7 +241,9 @@ describe('readme', () => {
const readme: string = await readReadme('mixed-html-mk');
expect(clean(parseReadme(readme) as string)).toMatchInlineSnapshot(
`"<h1 id=\\"mix-html-and-xss-markdown\\">mix html and XSS markdown</h1><p><a>Basic</a></p><p><a href=\\"https://github.com/webpack/webpack\\"><img src=\\"https://webpack.js.org/assets/icon-square-big.svg\\" height=\\"200\\" width=\\"200\\"></a></p>"`
'"<h1 id=\\"mix-html-and-xss-markdown\\">mix html and XSS markdown</h1><p><a>Basic<' +
'/a></p><p><a href=\\"https://github.com/webpack/webpack\\"><img src=\\"https://webp' +
'ack.js.org/assets/icon-square-big.svg\\" height=\\"200\\" width=\\"200\\"></a></p>"'
);
});
});

View file

@ -514,7 +514,8 @@ declare module '@verdaccio/types' {
tag?: string;
}
// FIXME: error should be export type `VerdaccioError = HttpError & { code: number };` instead of AuthError
// FIXME: error should be export type `VerdaccioError = HttpError & { code: number };`
// instead of AuthError
// but this type is on @verdaccio/commons-api and cannot be used here yet (I don't know why)
interface HttpError extends Error {
status: number;

View file

@ -7,13 +7,9 @@ import { parseConfigurationFile } from './__helper';
const parseConfigurationNotifyFile = (name) => {
return parseConfigurationFile(`notify/${name}`);
};
const singleNotificationConfig = parseConfigFile(parseConfigurationNotifyFile('single.notify'));
const singleHeaderNotificationConfig = parseConfigFile(
parseConfigurationNotifyFile('single.header.notify')
);
const packagePatternNotificationConfig = parseConfigFile(
parseConfigurationNotifyFile('single.packagePattern.notify')
);
const multiNotificationConfig = parseConfigFile(parseConfigurationNotifyFile('multiple.notify'));
const mockInfo = jest.fn();

View file

@ -42,7 +42,8 @@ function isES6(plugin): boolean {
* Load a plugin following the rules
* - First try to load from the internal directory plugins (which will disappear soon or later).
* - A second attempt from the external plugin directory
* - A third attempt from node_modules, in case to have multiple match as for instance verdaccio-ldap
* - A third attempt from node_modules, in case to have multiple match as for instance
* verdaccio-ldap
* and sinopia-ldap. All verdaccio prefix will have preferences.
* @param {*} config a reference of the configuration settings
* @param {*} pluginConfigs

View file

@ -68,7 +68,8 @@ describe('formatter', () => {
error: undefined,
bytes: { in: 0, out: 150186 },
msg:
"@{status}, user: @{user}(@{remoteIP}), req: '@{request.method} @{request.url}', bytes: @{bytes.in}/@{bytes.out}",
"@{status}, user: @{user}(@{remoteIP}), req: '@{request.method} @{request.url}', " +
'bytes: @{bytes.in}/@{bytes.out}',
};
expect(printMessage(log, prettyfierOptions)).toMatchSnapshot();

View file

@ -85,7 +85,8 @@ export function setup(options: LoggerConfig | LoggerConfigItem = [DEFAULT_LOGGER
const isLegacyConf = _.isArray(options);
if (isLegacyConf) {
// FIXME: re-enable later
// console.warn("DEPRECATE: logs does not have multi-stream support anymore, please upgrade your logger configuration");
// console.warn("DEPRECATE: logs does not have multi-stream support anymore,
// please upgrade your logger configuration");
}
// backward compatible, pick only the first option

View file

@ -61,7 +61,8 @@ export function setSecurityWebHeaders(
}
// flow: express does not match properly
// flow info https://github.com/flowtype/flow-typed/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+express
// flow info
// https://github.com/flowtype/flow-typed/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+express
export function validateName(
req: $RequestExtend,
res: $ResponseExtend,
@ -80,7 +81,8 @@ export function validateName(
}
// flow: express does not match properly
// flow info https://github.com/flowtype/flow-typed/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+express
// flow info
// https://github.com/flowtype/flow-typed/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+express
export function validatePackage(
req: $RequestExtend,
res: $ResponseExtend,

View file

@ -54,7 +54,8 @@ export default class VerdaccioProcess implements IServerProcess {
this.childFork = fork(verdaccioPath, ['-c', configPath, '-l', port as string], childOptions);
this.childFork.on('message', (msg) => {
// verdaccio_started is a message that comes from verdaccio in debug mode that notify has been started
// verdaccio_started is a message that comes from verdaccio in debug mode that
// notify has been started
if ('verdaccio_started' in msg) {
this.bridge
.debug()

View file

@ -35,7 +35,8 @@ export function generateNewVersion(
},
dist: {
integrity:
'sha512-zVEqt1JUCOPsash9q4wMkJEDPD+QCx95TRhQII+JnoS31uBUKoZxhzvvUJCcLVy2CQG4QdwXARU7dYWPnrwhGg==',
'sha512-zVEqt1JUCOPsash9q4wMkJEDPD+QCx95TRhQII+JnoS31uBUKoZxhzvvUJCcLVy2CQG4Q' +
'dwXARU7dYWPnrwhGg==',
shasum: shashum,
tarball: `http:\/\/localhost:4873\/${pkgName}\/-\/${pkgName}-${version}.tgz`,
},

View file

@ -115,7 +115,8 @@ function logHTTPSWarning(storageLocation) {
function handleHTTPS(app: Application, configPath: string, config: ConfigWithHttps): https.Server {
try {
let httpsOptions = {
secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3, // disable insecure SSLv2 and SSLv3
// disable insecure SSLv2 and SSLv3
secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3,
};
const keyCertConfig = config.https as HttpsConfKeyCert;

View file

@ -4,7 +4,8 @@ export function displayExperimentsInfoBox(experiments) {
const experimentList = Object.keys(experiments);
if (experimentList.length >= 1) {
logger.logger.warn(
'⚠️ experiments are enabled, we recommend do not use experiments in production, comment out this section to disable it'
'⚠️ experiments are enabled, we recommend do not use experiments in production, ' +
'comment out this section to disable it'
);
experimentList.forEach((experiment) => {
logger.logger.warn(

View file

@ -1,4 +1,4 @@
import { API_ERROR, certPem, csrPem, keyPem } from '@verdaccio/dev-commons';
import { certPem, csrPem, keyPem } from '@verdaccio/dev-commons';
import { resolveConfigPath } from './cli-utils';

View file

@ -228,7 +228,8 @@ class ProxyStorage implements IProxy {
message += error ? ', error: @{!error}' : ', bytes: @{bytes.in}/@{bytes.out}';
self.logger.warn(
{
err: err || undefined, // if error is null/false change this to undefined so it wont log
// if error is null/false change this to undefined so it wont log
err: err || undefined,
request: { method: method, url: uri },
level: 35, // http
status: res != null ? res.statusCode : 'ERR',
@ -291,6 +292,7 @@ class ProxyStorage implements IProxy {
})();
}
});
// eslint-disable-next-line @typescript-eslint/no-unused-vars
req.on('error', function (_err): void {
// FIXME: _verdaccio_aborted seems not used
// @ts-ignore

View file

@ -31,7 +31,8 @@ const json = {
_npmUser: {},
dist: {
integrity:
'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr9cmE6dUBf+XoPoH4g==',
'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjc' +
'r9cmE6dUBf+XoPoH4g==',
shasum: '2c03764f651a9f016ca0b7620421457b619151b9',
tarball: 'http://localhost:5555/@scope/pk1-test/-/@scope/pk1-test-1.0.6.tgz',
},
@ -42,7 +43,15 @@ const json = {
'@scope/pk1-test-1.0.6.tgz': {
content_type: 'application/octet-stream',
data:
'H4sIAAAAAAAAE+2W32vbMBDH85y/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo//79KPeQsnIw5KUDX/9IOvurLuz/DHSjK/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1aW8eML+Vv10m9oF/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0ScCdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yoEHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS/pLQe+D+FIv/agIWI6GX66kFuIhT+1gDjrp/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0/jWiAK8OcMjt8MW3OlfQppcuhhQ6k+2OgkK2Q8DssFPi/IHpU9fz3/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6/f88f/Pu47zomiPk2Lv/dOv8h+P/34/D/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=',
'H4sIAAAAAAAAE+2W32vbMBDH85y/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo//79KPeQsnI' +
'w5KUDX/9IOvurLuz/DHSjK/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1a' +
'W8eML+Vv10m9oF/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0Sc' +
'CdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y' +
'7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yo' +
'EHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS/pLQe+D+FIv/agIWI6GX66kFuIhT+' +
'1gDjrp/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0/jWiAK8OcMjt8MW3OlfQppcuhhQ6k' +
'+2OgkK2Q8DssFPi/IHpU9fz3/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6/f88f/Pu47zomiPk2Lv/dOv8' +
'h+P/34/D/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=',
length: 512,
},
},

View file

@ -27,7 +27,8 @@ export function generateVersion(pkgName, version) {
},
dist: {
integrity:
'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr9cmE6dUBf+XoPoH4g==',
'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr9c' +
'mE6dUBf+XoPoH4g==',
shasum: '2c03764f651a9f016ca0b7620421457b619151b9', // pragma: allowlist secret
tarball: `http:\/\/localhost:5555\/${pkgName}\/-\/${pkgName}-${version}.tgz`,
},
@ -107,7 +108,8 @@ export function generatePackageMetadata(pkgName: string, version = '1.0.0'): Pac
},
dist: {
integrity:
'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr9cmE6dUBf+XoPoH4g==',
'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr' +
'9cmE6dUBf+XoPoH4g==',
shasum: '2c03764f651a9f016ca0b7620421457b619151b9', // pragma: allowlist secret
tarball: `http:\/\/localhost:5555\/${pkgName}\/-\/${pkgName}-${version}.tgz`,
},
@ -118,7 +120,15 @@ export function generatePackageMetadata(pkgName: string, version = '1.0.0'): Pac
[`${pkgName}-${version}.tgz`]: {
content_type: 'application/octet-stream',
data:
'H4sIAAAAAAAAE+2W32vbMBDH85y/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo//79KPeQsnIw5KUDX/9IOvurLuz/DHSjK/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1aW8eML+Vv10m9oF/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0ScCdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yoEHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS/pLQe+D+FIv/agIWI6GX66kFuIhT+1gDjrp/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0/jWiAK8OcMjt8MW3OlfQppcuhhQ6k+2OgkK2Q8DssFPi/IHpU9fz3/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6/f88f/Pu47zomiPk2Lv/dOv8h+P/34/D/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=',
'H4sIAAAAAAAAE+2W32vbMBDH85y/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo//79KPeQsnI' +
'w5KUDX/9IOvurLuz/DHSjK/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1a' +
'W8eML+Vv10m9oF/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0Sc' +
'CdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y' +
'7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yo' +
'EHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS/pLQe+D+FIv/agIWI6GX66kFuIhT+' +
'1gDjrp/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0/jWiAK8OcMjt8MW3OlfQppcuhhQ6k' +
'+2OgkK2Q8DssFPi/IHpU9fz3/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6/f88f/Pu47zomiPk2Lv/dOv8' +
'h+P/34/D/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=',
length: 512,
},
},

View file

@ -536,17 +536,18 @@ describe('endpoint unit test', () => {
/**
* Context:
*
* 'non-unpublish':
access: $authenticated
publish: jota_unpublish_fail
# There is some conditions to keep on mind here
# - If unpublish is empty, fallback with the publish value
# - If the user has permissions to publish and this empty it will be allowed to unpublish
# - If we want to forbid anyone to unpublish, just write here any unexisting user
unpublish: none
The result of this test should fail and even if jota_unpublish_fail is allowed to publish.
* 'non-unpublish':
* access: $authenticated
* publish: jota_unpublish_fail
* # There is some conditions to keep on mind here
* # - If unpublish is empty, fallback with the publish value
* # - If the user has permissions to publish and this empty it will
* # be allowed to unpublish
* # - If we want to forbid anyone to unpublish, just write here any non-existing user
* unpublish: none
*
* The result of this test should fail and even if jota_unpublish_fail is
* allowed to publish.
*
*/
const credentials = { name: 'jota_unpublish_fail', password: 'secretPass' };
@ -590,10 +591,11 @@ describe('endpoint unit test', () => {
# There is some conditions to keep on mind here
# - If unpublish is empty, fallback with the publish value
# - If the user has permissions to publish and this empty it will be allowed to unpublish
# - If we want to forbid anyone to unpublish, just write here any unexisting user
# - If we want to forbid anyone to unpublish, just write here any non-existing user
unpublish: none
The result of this test should fail and even if jota_unpublish_fail is allowed to publish.
The result of this test should fail and even if jota_unpublish_fail is allowed
to publish.
*
*/
@ -823,35 +825,38 @@ describe('endpoint unit test', () => {
done();
});
test('should require both publish and unpublish access to (un)deprecate a package', async () => {
let credentials = { name: 'only_publish', password: 'secretPass' };
let token = await getNewToken(request(app), credentials);
const pkg = generateDeprecateMetadata(pkgName, version, 'get deprecated');
const [err, res] = await putPackage(
request(app),
`/${encodeScopedUri(pkgName)}`,
pkg,
token
);
expect(err).not.toBeNull();
expect(res.body.error).toBeDefined();
expect(res.body.error).toMatch(
/user only_publish is not allowed to unpublish package @scope\/deprecate/
);
credentials = { name: 'only_unpublish', password: 'secretPass' };
token = await getNewToken(request(app), credentials);
const [err2, res2] = await putPackage(
request(app),
`/${encodeScopedUri(pkgName)}`,
pkg,
token
);
expect(err2).not.toBeNull();
expect(res2.body.error).toBeDefined();
expect(res2.body.error).toMatch(
/user only_unpublish is not allowed to publish package @scope\/deprecate/
);
});
test(
'should require both publish and unpublish access to ' + '(un)deprecate a package',
async () => {
let credentials = { name: 'only_publish', password: 'secretPass' };
let token = await getNewToken(request(app), credentials);
const pkg = generateDeprecateMetadata(pkgName, version, 'get deprecated');
const [err, res] = await putPackage(
request(app),
`/${encodeScopedUri(pkgName)}`,
pkg,
token
);
expect(err).not.toBeNull();
expect(res.body.error).toBeDefined();
expect(res.body.error).toMatch(
/user only_publish is not allowed to unpublish package @scope\/deprecate/
);
credentials = { name: 'only_unpublish', password: 'secretPass' };
token = await getNewToken(request(app), credentials);
const [err2, res2] = await putPackage(
request(app),
`/${encodeScopedUri(pkgName)}`,
pkg,
token
);
expect(err2).not.toBeNull();
expect(res2.body.error).toBeDefined();
expect(res2.body.error).toMatch(
/user only_unpublish is not allowed to publish package @scope\/deprecate/
);
}
);
test('should deprecate multiple packages', async (done) => {
await putPackage(

View file

@ -13,7 +13,8 @@ class FilterPlugin {
}
// Example filter that removes a single blocked package
if (this._config.pkg === pkg.name) {
// In reality, we also want to remove references in attachments and dist-tags, etc. This is just a POC
// In reality, we also want to remove references in attachments and dist-tags,
// etc. This is just a POC
delete pkg.versions[this._config.version];
}
resolve(pkg);

View file

@ -136,30 +136,34 @@ describe('endpoint user auth JWT unit test', () => {
done();
});
test('should fails on login if user credentials are invalid even if jwt valid token is provided', async (done) => {
const credentials = { name: 'newFailsUser', password: 'secretPass' };
const [err, res] = await addUser(request(app), credentials.name, credentials);
expect(err).toBeNull();
expect(res.body.ok).toBeDefined();
expect(res.body.token).toBeDefined();
test(
'should fails on login if user credentials are invalid even if jwt' +
' valid token is provided',
async (done) => {
const credentials = { name: 'newFailsUser', password: 'secretPass' };
const [err, res] = await addUser(request(app), credentials.name, credentials);
expect(err).toBeNull();
expect(res.body.ok).toBeDefined();
expect(res.body.token).toBeDefined();
const { token } = res.body;
expect(typeof token).toBe('string');
expect(res.body.ok).toMatch(`user '${credentials.name}' created`);
const { token } = res.body;
expect(typeof token).toBe('string');
expect(res.body.ok).toMatch(`user '${credentials.name}' created`);
// we login when token is valid
const newCredentials = { name: 'newFailsUser', password: 'BAD_PASSWORD' };
const [err2, resp2] = await loginUserToken(
request(app),
newCredentials.name,
newCredentials,
token,
HTTP_STATUS.UNAUTHORIZED
);
expect(err2).toBeNull();
expect(resp2.statusCode).toBe(HTTP_STATUS.UNAUTHORIZED);
expect(resp2.body.error).toMatch(API_ERROR.BAD_USERNAME_PASSWORD);
// we login when token is valid
const newCredentials = { name: 'newFailsUser', password: 'BAD_PASSWORD' };
const [err2, resp2] = await loginUserToken(
request(app),
newCredentials.name,
newCredentials,
token,
HTTP_STATUS.UNAUTHORIZED
);
expect(err2).toBeNull();
expect(resp2.statusCode).toBe(HTTP_STATUS.UNAUTHORIZED);
expect(resp2.body.error).toMatch(API_ERROR.BAD_USERNAME_PASSWORD);
done();
});
done();
}
);
});

View file

@ -111,47 +111,52 @@ describe('StorageTest', () => {
});
describe('test getTarball', () => {
test.skip('should select right uplink given package.proxy for upstream tarballs', async (done) => {
const storage: IStorageHandler = await generateSameUplinkStorage();
const notcachedSpy = jest.spyOn(storage.uplinks.notcached, 'fetchTarball');
const cachedSpy = jest.spyOn(storage.uplinks.cached, 'fetchTarball');
test.skip(
'should select right uplink given package.proxy for' + ' upstream tarballs',
async (done) => {
const storage: IStorageHandler = await generateSameUplinkStorage();
const notcachedSpy = jest.spyOn(storage.uplinks.notcached, 'fetchTarball');
const cachedSpy = jest.spyOn(storage.uplinks.cached, 'fetchTarball');
await new Promise((res, rej) => {
const reader = storage.getTarball('jquery', 'jquery-1.5.1.tgz');
reader.on('end', () => {
expect(notcachedSpy).toHaveBeenCalledTimes(0);
expect(cachedSpy).toHaveBeenCalledTimes(1);
expect(cachedSpy).toHaveBeenCalledWith('http://0.0.0.0:55548/jquery/-/jquery-1.5.1.tgz');
res();
await new Promise((res, rej) => {
const reader = storage.getTarball('jquery', 'jquery-1.5.1.tgz');
reader.on('end', () => {
expect(notcachedSpy).toHaveBeenCalledTimes(0);
expect(cachedSpy).toHaveBeenCalledTimes(1);
expect(cachedSpy).toHaveBeenCalledWith(
'http://0.0.0.0:55548/jquery/-/jquery-1.5.1.tgz'
);
res();
});
reader.on('error', (err) => {
rej(err);
});
reader.pipe(createNullStream());
});
reader.on('error', (err) => {
rej(err);
});
reader.pipe(createNullStream());
});
// Reset counters.
cachedSpy.mockClear();
notcachedSpy.mockClear();
// Reset counters.
cachedSpy.mockClear();
notcachedSpy.mockClear();
await new Promise((res, rej) => {
const reader = storage.getTarball('@jquery/jquery', 'jquery-1.5.1.tgz');
reader.on('end', () => {
expect(cachedSpy).toHaveBeenCalledTimes(0);
expect(notcachedSpy).toHaveBeenCalledTimes(1);
expect(notcachedSpy).toHaveBeenCalledWith(
'http://0.0.0.0:55548/@jquery%2fjquery/-/jquery-1.5.1.tgz'
);
res();
await new Promise((res, rej) => {
const reader = storage.getTarball('@jquery/jquery', 'jquery-1.5.1.tgz');
reader.on('end', () => {
expect(cachedSpy).toHaveBeenCalledTimes(0);
expect(notcachedSpy).toHaveBeenCalledTimes(1);
expect(notcachedSpy).toHaveBeenCalledWith(
'http://0.0.0.0:55548/@jquery%2fjquery/-/jquery-1.5.1.tgz'
);
res();
});
reader.on('error', (err) => {
rej(err);
});
reader.pipe(createNullStream());
});
reader.on('error', (err) => {
rej(err);
});
reader.pipe(createNullStream());
});
done();
});
done();
}
);
});
describe('test _syncUplinksMetadata', () => {

View file

@ -269,7 +269,8 @@ class LocalStorage implements IStorage {
return cb(ErrorCode.getConflict());
}
// if uploaded tarball has a different shasum, it's very likely that we have some kind of error
// if uploaded tarball has a different shasum, it's very likely that we
// have some kind of error
if (isObject(metadata.dist) && _.isString(metadata.dist.tarball)) {
const tarball = metadata.dist.tarball.replace(/.*\//, '');
@ -279,7 +280,9 @@ class LocalStorage implements IStorage {
_.isNil(metadata.dist.shasum) === false
) {
if (data._attachments[tarball].shasum != metadata.dist.shasum) {
const errorMessage = `shasum error, ${data._attachments[tarball].shasum} != ${metadata.dist.shasum}`;
const errorMessage =
`shasum error, ` +
`${data._attachments[tarball].shasum} != ${metadata.dist.shasum}`;
return cb(ErrorCode.getBadRequest(errorMessage));
}
}

View file

@ -74,7 +74,8 @@ export function getLatestReadme(pkg: Package): string {
return readme;
}
// In case of empty readme - trying to get ANY readme in the following order: 'next','beta','alpha','test','dev','canary'
// In case of empty readme - trying to get ANY readme in the following order:
// 'next','beta','alpha','test','dev','canary'
const readmeDistTagsPriority = ['next', 'beta', 'alpha', 'test', 'dev', 'canary'];
readmeDistTagsPriority.forEach(function (tag): string | void {
if (readme) {

View file

@ -665,13 +665,15 @@ class Storage {
if (err) {
return callback(err);
}
// Any error here will cause a 404, like an uplink error. This is likely the right thing to do
// Any error here will cause a 404, like an uplink error. This is likely
// the right thing to do
// as a broken filter is a security risk.
const filterErrors: Error[] = [];
// This MUST be done serially and not in parallel as they modify packageJsonLocal
for (const filter of self.filters) {
try {
// These filters can assume it's save to modify packageJsonLocal and return it directly for
// These filters can assume it's save to modify packageJsonLocal
// and return it directly for
// performance (i.e. need not be pure)
packageJsonLocal = await filter.filter_metadata(packageJsonLocal);
} catch (err) {

View file

@ -5,13 +5,13 @@ import { Config as AppConfig } from '@verdaccio/config';
// @ts-ignore
import { logger, setup } from '@verdaccio/logger';
import { configExample, generateNewVersion } from '@verdaccio/mock';
import { IStorage } from '../src/storage';
const readMetadata = (fileName = 'metadata') => readFile(`../fixtures/${fileName}`).toString();
import { Config, MergeTags, Package } from '@verdaccio/types';
import { API_ERROR, HTTP_STATUS, DIST_TAGS } from '@verdaccio/dev-commons';
import { VerdaccioError } from '@verdaccio/commons-api';
import { LocalStorage } from '../src/local-storage';
import { IStorage } from '../src/storage';
import { generatePackageTemplate } from '../src/storage-utils';
import { readFile } from './fixtures/test.utils';

View file

@ -1,5 +1,4 @@
import {
IBasicAuth,
IBasicStorage,
IStorageManager,
UpLinkConf,
@ -9,7 +8,6 @@ import {
RemoteUser,
Config,
Logger,
JWTSignOptions,
PackageAccess,
IPluginStorage,
StringValue as verdaccio$StringValue,
@ -17,7 +15,6 @@ import {
Package,
IPluginStorageFilter,
Author,
AuthPluginPackage,
Token,
ITokenActions,
TokenFilter,

View file

@ -1,5 +1,4 @@
import { API_ERROR, ROLES } from '@verdaccio/dev-commons';
import { VerdaccioError, getForbidden } from '@verdaccio/commons-api';
import { ROLES } from '@verdaccio/dev-commons';
import {
createAnonymousRemoteUser,
createRemoteUser,

View file

@ -127,38 +127,41 @@ describe('Config Utilities', () => {
expect(all.publish).toContain('admin');
});
test('should normalize deprecated packages into the new ones (backward props compatible)', () => {
const { packages } = parseConfigFile(parseConfigurationFile('deprecated-pkgs-basic'));
const access = normalisePackageAccess(packages);
test(
'should normalize deprecated packages into the new ones ' + '(backward props compatible)',
() => {
const { packages } = parseConfigFile(parseConfigurationFile('deprecated-pkgs-basic'));
const access = normalisePackageAccess(packages);
expect(access).toBeDefined();
expect(access).toBeDefined();
const scoped = access[`${PACKAGE_ACCESS.SCOPE}`];
const all = access[`${PACKAGE_ACCESS.ALL}`];
const react = access['react-*'];
const scoped = access[`${PACKAGE_ACCESS.SCOPE}`];
const all = access[`${PACKAGE_ACCESS.ALL}`];
const react = access['react-*'];
expect(react).toBeDefined();
expect(react.access).toBeDefined();
expect(react).toBeDefined();
expect(react.access).toBeDefined();
// Intended checks, Typescript should catch this, we test the runtime part
// @ts-ignore
expect(react.access).toEqual([]);
// @ts-ignore
expect(react.publish[0]).toBe('admin');
expect(react.proxy).toBeDefined();
// @ts-ignore
expect(react.proxy).toEqual([]);
expect(react.storage).toBeDefined();
// Intended checks, Typescript should catch this, we test the runtime part
// @ts-ignore
expect(react.access).toEqual([]);
// @ts-ignore
expect(react.publish[0]).toBe('admin');
expect(react.proxy).toBeDefined();
// @ts-ignore
expect(react.proxy).toEqual([]);
expect(react.storage).toBeDefined();
expect(react.storage).toBe('react-storage');
expect(scoped).toBeDefined();
expect(scoped.storage).not.toBeDefined();
expect(all).toBeDefined();
expect(all.access).toBeDefined();
expect(all.storage).not.toBeDefined();
expect(all.publish).toBeDefined();
expect(all.proxy).toBeDefined();
});
expect(react.storage).toBe('react-storage');
expect(scoped).toBeDefined();
expect(scoped.storage).not.toBeDefined();
expect(all).toBeDefined();
expect(all.access).toBeDefined();
expect(all.storage).not.toBeDefined();
expect(all.publish).toBeDefined();
expect(all.proxy).toBeDefined();
}
);
test('should check not default packages access', () => {
const { packages } = parseConfigFile(parseConfigurationFile('pkgs-empty'));

View file

@ -23,7 +23,8 @@ class FunctionalEnvironment extends NodeEnvironment {
public async setup() {
// const SILENCE_LOG = !process.env.VERDACCIO_PROCESS_SILENCE || false;
// @ts-ignore
// const DEBUG_INJECT: boolean = process.env.VERDACCIO_DEBUG_INJECT ? process.env.VERDACCIO_DEBUG_INJECT : false;
// const DEBUG_INJECT: boolean = process.env.VERDACCIO_DEBUG_INJECT ?
// process.env.VERDACCIO_DEBUG_INJECT : false;
const forkList: any = [];
const serverList: any = [];
const pathStore = path.join(__dirname, '../store');

View file

@ -73,7 +73,8 @@ export default function (server, server2) {
.then(function (body) {
expect(body.name).toEqual(SCOPE);
expect(body.dist.tarball).toEqual(
`http://${DOMAIN_SERVERS}:${PORT_SERVER_2}/@test%2fscoped/-/${PKG_NAME}-${PKG_VERSION}.tgz`
`http://${DOMAIN_SERVERS}:${PORT_SERVER_2}/@test%2fscoped/-/${PKG_NAME}-` +
`${PKG_VERSION}.tgz`
);
});
});

View file

@ -10,7 +10,9 @@ const defaultPkg = {
version: '0.1.0',
dist: {
shasum: 'fake',
tarball: `http://${DOMAIN_SERVERS}:${PORT_SERVER_APP}/testexp-incomplete/-/content-length.tar.gz`,
tarball:
`http://${DOMAIN_SERVERS}:${PORT_SERVER_APP}/testexp-incomplete/-` +
`/content-length.tar.gz`,
},
},
'0.1.1': {

View file

@ -62,14 +62,18 @@ export default function (server, server2) {
/* test for before() */
});
test(`should fetch the newly created published tarball for ${PKG_NAME} from server1 on server2`, () => {
return server
.getTarball(PKG_NAME, TARBALL)
.status(HTTP_STATUS.OK)
.then(function (body) {
expect(body).toEqual(getBinary());
});
});
test(
`should fetch the newly created published tarball for ${PKG_NAME} ` +
`from server1 on server2`,
() => {
return server
.getTarball(PKG_NAME, TARBALL)
.status(HTTP_STATUS.OK)
.then(function (body) {
expect(body).toEqual(getBinary());
});
}
);
test(`should fetch metadata for ${PKG_NAME} match from server1`, () => {
return server

View file

@ -15,7 +15,9 @@ export default function (server, express) {
version: '0.1.0',
dist: {
shasum: 'fake',
tarball: `http://${DOMAIN_SERVERS}:${PORT_SERVER_APP}/testexp-racycrash/-/test.tar.gz`,
tarball:
`http://${DOMAIN_SERVERS}:${PORT_SERVER_APP}/testexp-racycrash/-` +
`/test.tar.gz`,
},
},
},

View file

@ -48,7 +48,8 @@ export default function (server) {
return server
.request({
uri:
'/testpkg-sec/-/%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd',
'/testpkg-sec/-/%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%' +
'2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd',
})
.status(HTTP_STATUS.FORBIDDEN)
.body_error(/invalid filename/);

View file

@ -1,7 +1,8 @@
/**
* PLEASE DO NOT MODIFY THIS FILE
*
* This test is just for teaching purpose, use this example as template for your new endpoint API unit test
* This test is just for teaching purpose, use this example as template for your new
* endpoint API unit test
*
* If you have any questions, ask at the http://chat.verdaccio.org #questions channel.
*

View file

@ -4,7 +4,15 @@ export function generateAttachment() {
return {
content_type: 'application/octet-stream',
data:
'H4sIAAAAAAAAE+2W32vbMBDH85y/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo//79KPeQsnIw5KUDX/9IOvurLuz/DHSjK/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1aW8eML+Vv10m9oF/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0ScCdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yoEHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS/pLQe+D+FIv/agIWI6GX66kFuIhT+1gDjrp/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0/jWiAK8OcMjt8MW3OlfQppcuhhQ6k+2OgkK2Q8DssFPi/IHpU9fz3/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6/f88f/Pu47zomiPk2Lv/dOv8h+P/34/D/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=',
'H4sIAAAAAAAAE+2W32vbMBDH85y/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo//79KPeQsnI' +
'w5KUDX/9IOvurLuz/DHSjK/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1a' +
'W8eML+Vv10m9oF/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0Sc' +
'CdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y' +
'7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yo' +
'EHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS/pLQe+D+FIv/agIWI6GX66kFuIhT+' +
'1gDjrp/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0/jWiAK8OcMjt8MW3OlfQppcuhhQ6k' +
'+2OgkK2Q8DssFPi/IHpU9fz3/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6/f88f/Pu47zomiPk2Lv/dOv8' +
'h+P/34/D/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=',
length: 512,
};
}
@ -36,7 +44,8 @@ export function generateVersion(pkgName, version) {
},
dist: {
integrity:
'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr9cmE6dUBf+XoPoH4g==',
'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr9cmE6' +
'dUBf+XoPoH4g==',
shasum: '2c03764f651a9f016ca0b7620421457b619151b9', // pragma: allowlist secret
tarball: `http:\/\/localhost:5555\/${pkgName}\/-\/${pkgName}-${version}.tgz`,
},