0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2025-03-25 02:32:52 -05:00

Merge pull request #1313 from verdaccio/4.1.x

4.1.x
This commit is contained in:
Juan Picado @jotadeveloper 2019-07-08 09:07:22 +02:00 committed by GitHub
commit 0061e380c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
66 changed files with 866 additions and 453 deletions

View file

@ -14,4 +14,5 @@ Dockerfile
*.scss
*.png
*.jpg
*.sh
test/unit/partials/

1
.gitignore vendored
View file

@ -6,6 +6,7 @@ build/
### Test
test/unit/partials/store/test-*-storage/*
test/unit/partials/store/*-storage/*
test/unit/partials/store/storage_default_storage/*
.verdaccio-db.json
.sinopia-db.json

View file

@ -28,6 +28,7 @@
"cookies": "0.7.3",
"cors": "2.8.5",
"dayjs": "1.8.14",
"envinfo": "7.3.1",
"express": "4.16.4",
"handlebars": "4.1.2",
"http-errors": "1.7.2",
@ -52,7 +53,7 @@
"@commitlint/config-conventional": "7.5.0",
"@octokit/rest": "16.25.0",
"@verdaccio/babel-preset": "0.1.0",
"@verdaccio/types": "5.0.0-beta.4",
"@verdaccio/types": "5.0.2",
"codecov": "3.3.0",
"cross-env": "5.2.0",
"eslint": "5.16.0",

View file

@ -20,7 +20,7 @@ import web from './web';
import type { $Application } from 'express';
import type { $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler, IAuth } from '../../types';
import type { Config as IConfig, IPluginMiddleware } from '@verdaccio/types';
import type { Config as IConfig, IPluginMiddleware, IPluginStorageFilter } from '@verdaccio/types';
import { setup, logger } from '../lib/logger';
import { log, final, errorReportingMiddleware } from './middleware';
@ -107,8 +107,14 @@ const defineAPI = function(config: IConfig, storage: IStorageHandler) {
export default (async function(configHash: any) {
setup(configHash.logs);
const config: IConfig = new AppConfig(_.cloneDeep(configHash));
// register middleware plugins
const plugin_params = {
config: config,
logger: logger,
};
const filters = loadPlugin(config, config.filters || {}, plugin_params, (plugin: IPluginStorageFilter) => plugin.filter_metadata);
const storage: IStorageHandler = new Storage(config);
// waits until init calls have been initialized
await storage.init(config);
await storage.init(config, filters);
return defineAPI(config, storage);
});

View file

@ -31,46 +31,67 @@ process.title = 'verdaccio';
const logger = require('./logger');
logger.setup(); // default setup
const envinfo = require('envinfo');
const commander = require('commander');
const pkgVersion = module.exports.version;
const pkgName = module.exports.name;
commander
.option('-i, --info', 'prints debugging information about the local environment')
.option('-l, --listen <[host:]port>', 'host:port number to listen on (default: localhost:4873)')
.option('-c, --config <config.yaml>', 'use this configuration file (default: ./config.yaml)')
.version(pkgVersion)
.parse(process.argv);
if (commander.args.length == 1 && !commander.config) {
function init() {
let verdaccioConfiguration;
let configPathLocation;
const cliListener = commander.listen;
try {
configPathLocation = findConfigFile(commander.config);
verdaccioConfiguration = parseConfigFile(configPathLocation);
process.title = verdaccioConfiguration.web && verdaccioConfiguration.web.title || 'verdaccio';
if (!verdaccioConfiguration.self_path) {
verdaccioConfiguration.self_path = path.resolve(configPathLocation);
}
if (!verdaccioConfiguration.https) {
verdaccioConfiguration.https = {enable: false};
}
logger.logger.warn({file: configPathLocation}, 'config file - @{file}');
startVerdaccio(verdaccioConfiguration, cliListener, configPathLocation, pkgVersion, pkgName, listenDefaultCallback);
} catch (err) {
logger.logger.fatal({file: configPathLocation, err: err}, 'cannot open config file @{file}: @{!err.message}');
process.exit(1);
}
}
if (commander.info) {
// eslint-disable-next-line no-console
console.log('\nEnvironment Info:');
(async () => {
const data = await envinfo.run({
System: ['OS', 'CPU'],
Binaries: ['Node', 'Yarn', 'npm'],
Virtualization: ['Docker'],
Browsers: ['Chrome', 'Edge', 'Firefox', 'Safari'],
npmGlobalPackages: ['verdaccio'],
});
// eslint-disable-next-line no-console
console.log(data);
process.exit(1);
})();
} else if (commander.args.length == 1 && !commander.config) {
// handling "verdaccio [config]" case if "-c" is missing in command line
commander.config = commander.args.pop();
}
if (commander.args.length !== 0) {
init();
} else if (commander.args.length !== 0) {
commander.help();
}
let verdaccioConfiguration;
let configPathLocation;
const cliListener = commander.listen;
try {
configPathLocation = findConfigFile(commander.config);
verdaccioConfiguration = parseConfigFile(configPathLocation);
process.title = verdaccioConfiguration.web && verdaccioConfiguration.web.title || 'verdaccio';
if (!verdaccioConfiguration.self_path) {
verdaccioConfiguration.self_path = path.resolve(configPathLocation);
}
if (!verdaccioConfiguration.https) {
verdaccioConfiguration.https = {enable: false};
}
logger.logger.warn({file: configPathLocation}, 'config file - @{file}');
startVerdaccio(verdaccioConfiguration, cliListener, configPathLocation, pkgVersion, pkgName, listenDefaultCallback);
} catch (err) {
logger.logger.fatal({file: configPathLocation, err: err}, 'cannot open config file @{file}: @{!err.message}');
process.exit(1);
} else {
init();
}
process.on('uncaughtException', function(err) {
@ -79,4 +100,4 @@ process.on('uncaughtException', function(err) {
},
'uncaught exception, please report this\n@{err.stack}' );
process.exit(255);
});
});

View file

@ -19,10 +19,15 @@ export const certPem = 'verdaccio-cert.pem';
export const csrPem = 'verdaccio-csr.pem';
export const HEADERS = {
ACCEPT: 'Accept',
ACCEPT_ENCODING: 'Accept-Encoding',
USER_AGENT: 'User-Agent',
JSON: 'application/json',
CONTENT_TYPE: 'Content-type',
CONTENT_LENGTH: 'content-length',
TEXT_PLAIN: 'text/plain',
TEXT_HTML: 'text/html',
AUTHORIZATION: 'authorization',
FORWARDED_PROTO: 'X-Forwarded-Proto',
FRAMES_OPTIONS: 'X-Frame-Options',
CSP: 'Content-Security-Policy',

View file

@ -17,7 +17,7 @@ import { setupUpLinks, updateVersionsHiddenUpLink } from './uplink-util';
import { mergeVersions } from './metadata-utils';
import { ErrorCode, normalizeDistTags, validateMetadata, isObject } from './utils';
import type { IStorage, IProxy, IStorageHandler, ProxyList, StringValue, IGetPackageOptions, ISyncUplinks } from '../../types';
import type { Versions, Package, Config, MergeTags, Version, DistFile, Callback, Logger } from '@verdaccio/types';
import type { Versions, Package, Config, MergeTags, Version, DistFile, Callback, Logger, IPluginStorageFilter } from '@verdaccio/types';
import type { IReadTarball, IUploadTarball } from '@verdaccio/streams';
import { hasProxyTo } from './config-utils';
import { logger } from '../lib/logger';
@ -27,6 +27,7 @@ class Storage implements IStorageHandler {
config: Config;
logger: Logger;
uplinks: ProxyList;
filters: Array<IPluginStorageFilter>;
constructor(config: Config) {
this.config = config;
@ -34,7 +35,8 @@ class Storage implements IStorageHandler {
this.logger = logger.child();
}
init(config: Config) {
init(config: Config, filters: Array<IPluginStorageFilter> = []) {
this.filters = filters;
this.localStorage = new LocalStorage(this.config, logger);
return this.localStorage.getSecret(config);
@ -525,11 +527,24 @@ class Storage implements IStorageHandler {
return callback(null, packageInfo);
}
self.localStorage.updateVersions(name, packageInfo, function(err, packageJsonLocal: Package) {
self.localStorage.updateVersions(name, packageInfo, async (err, packageJsonLocal: Package) => {
if (err) {
return callback(err);
}
return callback(null, packageJsonLocal, upLinksErrors);
// 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 = [];
// 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
// performance (i.e. need not be pure)
packageJsonLocal = await filter.filter_metadata(packageJsonLocal);
} catch (err) {
filterErrors.push(err);
}
}
callback(null, packageJsonLocal, _.concat(upLinksErrors, filterErrors));
});
}
);

View file

@ -257,9 +257,9 @@ class ProxyStorage implements IProxy {
*/
_setHeaders(options: any) {
const headers = options.headers || {};
const accept = 'Accept';
const acceptEncoding = 'Accept-Encoding';
const userAgent = 'User-Agent';
const accept = HEADERS.ACCEPT;
const acceptEncoding = HEADERS.ACCEPT_ENCODING;
const userAgent = HEADERS.USER_AGENT;
headers[accept] = headers[accept] || contentTypeAccept;
headers[acceptEncoding] = headers[acceptEncoding] || 'gzip';
@ -278,7 +278,7 @@ class ProxyStorage implements IProxy {
_setAuth(headers: any) {
const { auth } = this.config;
if (_.isNil(auth) || headers['authorization']) {
if (_.isNil(auth) || headers[HEADERS.AUTHORIZATION]) {
return headers;
}
@ -344,7 +344,7 @@ class ProxyStorage implements IProxy {
}
type = _.upperFirst(type);
headers['authorization'] = buildToken(type, token);
headers[HEADERS.AUTHORIZATION] = buildToken(type, token);
}
/**
@ -405,7 +405,7 @@ class ProxyStorage implements IProxy {
const headers = {};
if (_.isNil(options.etag) === false) {
headers['If-None-Match'] = options.etag;
headers['Accept'] = contentTypeAccept;
headers[HEADERS.ACCEPT] = contentTypeAccept;
}
this.request(

View file

@ -13,7 +13,18 @@ import createError from 'http-errors';
// $FlowFixMe
import sanitizyReadme from '@verdaccio/readme';
import { HTTP_STATUS, API_ERROR, DEFAULT_PORT, DEFAULT_DOMAIN, DEFAULT_PROTOCOL, CHARACTER_ENCODING, HEADERS, DIST_TAGS, DEFAULT_USER } from './constants';
import {
HTTP_STATUS,
API_ERROR,
APP_ERROR,
DEFAULT_PORT,
DEFAULT_DOMAIN,
DEFAULT_PROTOCOL,
CHARACTER_ENCODING,
HEADERS,
DIST_TAGS,
DEFAULT_USER,
} from './constants';
import { generateGravatarUrl, GENERIC_AVATAR } from '../utils/user';
import type { Package } from '@verdaccio/types';
@ -381,8 +392,20 @@ export const ErrorCode = {
},
};
export function parseConfigFile(configPath: string): Object {
return YAML.safeLoad(fs.readFileSync(configPath, CHARACTER_ENCODING.UTF8));
export function parseConfigFile(configPath: string) {
try {
if (/\.ya?ml$/i.test(configPath)) {
return YAML.safeLoad(fs.readFileSync(configPath, CHARACTER_ENCODING.UTF8));
} else {
return require(configPath);
}
} catch (e) {
if (e.code !== 'MODULE_NOT_FOUND') {
e.message = APP_ERROR.CONFIG_NOT_VALID;
}
throw new Error(e);
}
}
/**

View file

@ -4,7 +4,7 @@ import _ from 'lodash';
import assert from 'assert';
import smartRequest from './request';
import type {IServerBridge} from '../types';
import {HEADERS, HTTP_STATUS, TOKEN_BASIC} from '../../src/lib/constants';
import {API_MESSAGE, HEADERS, HTTP_STATUS, TOKEN_BASIC} from '../../src/lib/constants';
import {buildToken} from "../../src/lib/utils";
import {CREDENTIALS} from "../functional/config.functional";
@ -80,7 +80,7 @@ export default class Server implements IServerBridge {
uri: `/${encodeURIComponent(name)}`,
method: 'PUT',
headers: {
'content-type': HEADERS.JSON,
[HEADERS.CONTENT_TYPE]: HEADERS.JSON,
},
}).send(data);
}
@ -94,7 +94,7 @@ export default class Server implements IServerBridge {
uri: `/${encodeURIComponent(name)}/${encodeURIComponent(version)}/-tag/latest`,
method: 'PUT',
headers: {
'content-type': HEADERS.JSON,
[HEADERS.CONTENT_TYPE]: HEADERS.JSON,
},
}).send(data);
}
@ -112,7 +112,7 @@ export default class Server implements IServerBridge {
uri: `/${encodeURIComponent(name)}/-/${encodeURIComponent(filename)}/whatever`,
method: 'PUT',
headers: {
'content-type': HEADERS.OCTET_STREAM,
[HEADERS.CONTENT_TYPE]: HEADERS.OCTET_STREAM,
},
}).send(data);
}
@ -122,7 +122,7 @@ export default class Server implements IServerBridge {
uri: `/${encodeURIComponent(name)}/-rev/whatever`,
method: 'DELETE',
headers: {
'content-type': HEADERS.JSON_CHARSET,
[HEADERS.CONTENT_TYPE]: HEADERS.JSON_CHARSET,
},
});
}
@ -132,7 +132,7 @@ export default class Server implements IServerBridge {
uri: `/${encodeURIComponent(name)}/-/${filename}/-rev/whatever`,
method: 'DELETE',
headers: {
'content-type': HEADERS.JSON_CHARSET,
[HEADERS.CONTENT_TYPE]: HEADERS.JSON_CHARSET,
},
});
}
@ -143,7 +143,7 @@ export default class Server implements IServerBridge {
uri: `/${encodeURIComponent(name)}/${encodeURIComponent(tag)}`,
method: 'PUT',
headers: {
'content-type': HEADERS.JSON,
[HEADERS.CONTENT_TYPE]: HEADERS.JSON,
},
}).send(JSON.stringify(version));
}
@ -153,8 +153,8 @@ export default class Server implements IServerBridge {
uri: `/${encodeURIComponent(name)}/-/${encodeURIComponent(filename)}/whatever`,
method: 'PUT',
headers: {
'content-type': HEADERS.OCTET_STREAM,
'content-length': size,
[HEADERS.CONTENT_TYPE]: HEADERS.OCTET_STREAM,
[HEADERS.CONTENT_LENGTH]: size,
},
timeout: 1000,
});
@ -184,7 +184,7 @@ export default class Server implements IServerBridge {
addPackage(name: string) {
return this.putPackage(name, require('../functional/fixtures/package')(name))
.status(HTTP_STATUS.CREATED)
.body_ok('created new package');
.body_ok(API_MESSAGE.PKG_CREATED);
}
whoami() {
@ -210,7 +210,7 @@ export default class Server implements IServerBridge {
uri: '/-/_debug',
method: 'GET',
headers: {
'content-type': HEADERS.JSON,
[HEADERS.CONTENT_TYPE]: HEADERS.JSON,
},
})
}

View file

@ -19,7 +19,7 @@ export function getPackage(
// $FlowFixMe
return new Promise((resolve) => {
request.get(`/${pkg}`)
.set('authorization', header)
.set(HEADERS.AUTHORIZATION, header)
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
.expect(statusCode)
.end(function(err, res) {
@ -91,7 +91,7 @@ export function postProfile(request: any, body: any, token: string, statusCode:
return new Promise((resolve) => {
request.post(`/-/npm/v1/user`)
.send(body)
.set('authorization', `Bearer ${token}`)
.set(HEADERS.AUTHORIZATION, `Bearer ${token}`)
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
.expect(statusCode)
.end(function(err, res) {

View file

@ -1,5 +1,5 @@
import path from 'path';
export const parseConfigurationFile = (name) => {
return path.join(__dirname, `./partials/config/yaml/${name}.yaml`);
return path.join(__dirname, `../partials/config/yaml/${name}.yaml`);
};

View file

@ -0,0 +1,63 @@
// @flow
import path from 'path';
import {DOMAIN_SERVERS} from '../../functional/config.functional';
import VerdaccioProcess from '../../lib/server_process';
import {VerdaccioConfig} from '../../lib/verdaccio-server';
import Server from '../../lib/server';
import type {IServerBridge} from '../../types';
/**
* Fork a Verdaccio process with a custom configuration.
*
* Usage:
*
* - Fork the process within the beforeAll body.
* - Define a storage (use a specific name)
* - Define a unique port (be careful with conflicts)
* - Set a configuration
* - await / mockServer
* - call done();
*
* beforeAll(function(done) {
const store = path.join(__dirname, '../partials/store/test-profile-storage');
const mockServerPort = 55544;
rimraf(store, async () => {
const parsedConfig = parseConfigFile(parseConfigurationProfile());
const configForTest = _.assign({}, _.cloneDeep(parsedConfig), {
storage: store,
auth: {
htpasswd: {
file: './test-profile-storage/.htpasswd'
}
},
self_path: store
});
app = await endPointAPI(configForTest);
mockRegistry = await mockServer(mockServerPort).init();
done();
});
On finish the test we must close the server
afterAll(function(done) {
mockRegistry[0].stop();
done();
});
*
*
* @param port
* @returns {VerdaccioProcess}
*/
export function mockServer(port: number) {
const pathStore = path.join(__dirname, '../partials');
const storePath = path.join(pathStore, '/mock-store');
const configPath = path.join(pathStore, '/config-unit-mock-server-test.yaml');
const verdaccioConfig = new VerdaccioConfig(storePath, configPath, `http://${DOMAIN_SERVERS}:${port}/`, port);
const server: IServerBridge = new Server(verdaccioConfig.domainPath);
return new VerdaccioProcess(verdaccioConfig, server, false, false, false);
}

View file

@ -1,18 +0,0 @@
// @flow
import path from 'path';
import {DOMAIN_SERVERS} from '../../functional/config.functional';
import VerdaccioProcess from '../../lib/server_process';
import {VerdaccioConfig} from '../../lib/verdaccio-server';
import Server from '../../lib/server';
import type {IServerBridge} from '../../types';
export function mockServer(port: number) {
const pathStore = path.join(__dirname, '../partials');
const verdaccioConfig = new VerdaccioConfig(
path.join(pathStore, '/mock-store'),
path.join(pathStore, '/config-unit-mock-server-test.yaml'), `http://${DOMAIN_SERVERS}:${port}/`, port);
const server: IServerBridge = new Server(verdaccioConfig.domainPath);
return new VerdaccioProcess(verdaccioConfig, server, false, false, false);
}

View file

@ -1,53 +0,0 @@
// ensure that all arguments are validated
const path = require('path');
/**
* Validate.
app.param('package', validate_pkg);
app.param('filename', validate_name);
app.param('tag', validate_name);
app.param('version', validate_name);
app.param('revision', validate_name);
app.param('token', validate_name);
*/
describe('api endpoint app.param()', () => {
// to avoid a failure on run test
test('empty block', () => {});
runTest('../endpoint/index.js');
});
function runTest(file) {
return function() {
let m;
const requirePath = path.normalize(path.join(__dirname + '/../../../src/api/web/', file));
const source = require('fs').readFileSync(requirePath, 'utf8');
const very_scary_regexp = /\n\s*app\.(\w+)\s*\(\s*(("[^"]*")|('[^']*'))\s*,/g;
const appParams = {};
// look up for matches in the source code
while ((m = very_scary_regexp.exec(source)) != null) {
if (m[1] === 'set') continue;
let inner = m[2].slice(1, m[2].length-1);
var t;
inner.split('/').forEach(function(x) {
t = x.match(/^:([^?:]*)\??$/);
if (m[1] === 'param') {
appParams[x] = 'ok';
} else if (t) {
appParams[t[1]] = appParams[t[1]] || m[0].trim();
}
});
}
Object.keys(appParams).forEach(function(param) {
test('should validate ":'+param+'"', () => {
expect(appParams[param]).toEqual('ok');
});
});
};
}

View file

@ -2,7 +2,7 @@
import _ from 'lodash';
import smartRequest, {PromiseAssert} from '../../lib/request';
import {mockServer} from '../api/mock';
import {mockServer} from '../__helper/mock';
import {HTTP_STATUS} from '../../../src/lib/constants';
import type {IRequestPromise} from '../../types';

View file

@ -3,26 +3,27 @@ import _ from 'lodash';
import path from 'path';
import rimraf from 'rimraf';
import { HEADERS, HTTP_STATUS } from '../../../src/lib/constants';
import configDefault from '../partials/config/config_access';
import endPointAPI from '../../../src/api/index';
import {mockServer} from './mock';
import {DOMAIN_SERVERS} from '../../functional/config.functional';
import { HEADERS, HTTP_STATUS } from '../../../../src/lib/constants';
import configDefault from '../../partials/config/config_access';
import endPointAPI from '../../../../src/api';
import {mockServer} from '../../__helper/mock';
import {DOMAIN_SERVERS} from '../../../functional/config.functional';
require('../../../src/lib/logger').setup([]);
require('../../../../src/lib/logger').setup([]);
describe('api with no limited access configuration', () => {
let app;
let mockRegistry;
const store = path.join(__dirname, '../../partials/store/pkg-access-spec');
beforeAll(function(done) {
const mockServerPort = 55530;
const store = path.join(__dirname, './partials/store/access-storage');
rimraf(store, async () => {
const configForTest = _.assign({}, _.cloneDeep(configDefault), {
auth: {
htpasswd: {
file: './access-storage/htpasswd-access-test'
file: './access-storage/htpasswd-pkg-access'
}
},
self_path: store,
@ -40,7 +41,6 @@ describe('api with no limited access configuration', () => {
});
afterAll(function(done) {
const store = path.join(__dirname, './partials/store/access-storage');
rimraf(store, (err) => {
if (err) {
mockRegistry[0].stop();

View file

@ -3,18 +3,18 @@ import _ from 'lodash';
import path from 'path';
import rimraf from 'rimraf';
import configDefault from '../partials/config/index';
import publishMetadata from '../partials/publish-api';
import starMetadata from '../partials/star-api';
import endPointAPI from '../../../src/api/index';
import configDefault from '../../partials/config';
import publishMetadata from '../../partials/publish-api';
import starMetadata from '../../partials/star-api';
import endPointAPI from '../../../../src/api';
import {HEADERS, API_ERROR, HTTP_STATUS, HEADER_TYPE, API_MESSAGE, TOKEN_BEARER} from '../../../src/lib/constants';
import {mockServer} from './mock';
import {DOMAIN_SERVERS} from '../../functional/config.functional';
import {buildToken} from '../../../src/lib/utils';
import {getNewToken} from './__api-helper';
import {HEADERS, API_ERROR, HTTP_STATUS, HEADER_TYPE, API_MESSAGE, TOKEN_BEARER} from '../../../../src/lib/constants';
import {mockServer} from '../../__helper/mock';
import {DOMAIN_SERVERS} from '../../../functional/config.functional';
import {buildToken} from '../../../../src/lib/utils';
import {getNewToken} from '../../__helper/api';
require('../../../src/lib/logger').setup([]);
require('../../../../src/lib/logger').setup([]);
const credentials = { name: 'jota', password: 'secretPass' };
const putPackage = (app, name, publishMetadata) => {
@ -33,7 +33,7 @@ describe('endpoint unit test', () => {
let mockRegistry;
beforeAll(function(done) {
const store = path.join(__dirname, '../store/test-storage-api-spec');
const store = path.join(__dirname, '../../partials/store/test-storage-api-spec');
const mockServerPort = 55549;
rimraf(store, async () => {
const configForTest = configDefault({
@ -42,6 +42,12 @@ describe('endpoint unit test', () => {
file: './test-storage-api-spec/.htpasswd'
}
},
filters: {
'../../modules/api/partials/plugin/filter': {
pkg: 'npm_test',
version: '2.0.0'
}
},
storage: store,
self_path: store,
uplinks: {
@ -128,7 +134,7 @@ describe('endpoint unit test', () => {
test('should fails on protected endpoint /-/auth-package bad format', (done) => {
request(app)
.get('/auth-package')
.set('authorization', 'FakeHader')
.set(HEADERS.AUTHORIZATION, 'FakeHader')
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
.expect(HTTP_STATUS.FORBIDDEN)
.end(function(err, res) {
@ -141,7 +147,7 @@ describe('endpoint unit test', () => {
test('should fails on protected endpoint /-/auth-package bad JWT Bearer format', (done) => {
request(app)
.get('/auth-package')
.set('authorization', TOKEN_BEARER)
.set(HEADERS.AUTHORIZATION, TOKEN_BEARER)
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
.expect(HTTP_STATUS.FORBIDDEN)
.end(function(err, res) {
@ -154,7 +160,7 @@ describe('endpoint unit test', () => {
test('should fails on protected endpoint /-/auth-package well JWT Bearer', (done) => {
request(app)
.get('/auth-package')
.set('authorization', buildToken(TOKEN_BEARER, '12345'))
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, '12345'))
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
.expect(HTTP_STATUS.FORBIDDEN)
.end(function(err, res) {
@ -186,7 +192,7 @@ describe('endpoint unit test', () => {
// we need it here, because token is required
request(app)
.get('/vue')
.set('authorization', buildToken(TOKEN_BEARER, token))
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token))
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
.expect(HTTP_STATUS.OK)
.end(function(err, res) {
@ -384,6 +390,37 @@ describe('endpoint unit test', () => {
});
});
test('be able to filter packages', (done) => {
request(app)
.get('/npm_test')
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
.expect(HTTP_STATUS.OK)
.end(function(err, res) {
if (err) {
return done(err);
}
// Filter out 2.0.0
expect(Object.keys(res.body.versions)).toEqual(['1.0.0']);
done();
});
});
test('should not found when a filter fails', (done) => {
request(app)
// Filter errors look like other uplink errors
.get('/trigger-filter-failure')
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
.expect(HTTP_STATUS.NOT_FOUND)
.end(function(err, res) {
if (err) {
return done(err);
}
done();
});
});
test('should forbid access to remote package', (done) => {
request(app)
@ -638,7 +675,7 @@ describe('endpoint unit test', () => {
const token = await getNewToken(request(app), credentials);
request(app)
.put('/@scope%2fpk1-test')
.set('authorization', buildToken(TOKEN_BEARER, token))
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token))
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
.send(JSON.stringify({
...starMetadata,
@ -653,7 +690,7 @@ describe('endpoint unit test', () => {
}
request(app)
.get('/-/_view/starredByUser')
.set('authorization', buildToken(TOKEN_BEARER, token))
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token))
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
.send(JSON.stringify({
key: [credentials.name]
@ -682,7 +719,7 @@ describe('endpoint unit test', () => {
request(app)
.del('/@scope%2fpk1-test/-rev/4-6abcdb4efd41a576')
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
.set('authorization', buildToken(TOKEN_BEARER, token))
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token))
.expect(HTTP_STATUS.CREATED)
.end(function(err, res) {
if (err) {
@ -701,7 +738,7 @@ describe('endpoint unit test', () => {
request(app)
.del('/non-unpublish/-rev/4-6abcdb4efd41a576')
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
.set('authorization', buildToken(TOKEN_BEARER, token))
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token))
.expect(HTTP_STATUS.FORBIDDEN)
.end(function(err, res) {
expect(err).toBeNull();
@ -717,7 +754,7 @@ describe('endpoint unit test', () => {
request(app)
.put('/super-admin-can-unpublish')
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
.set('authorization', buildToken(TOKEN_BEARER, token))
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token))
.send(JSON.stringify(_.assign({}, publishMetadata, {
name: 'super-admin-can-unpublish'
})))
@ -734,7 +771,7 @@ describe('endpoint unit test', () => {
request(app)
.del('/super-admin-can-unpublish/-rev/4-6abcdb4efd41a576')
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
.set('authorization', buildToken(TOKEN_BEARER, token))
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token))
.expect(HTTP_STATUS.CREATED)
.end(function(err, res) {
expect(err).toBeNull();
@ -751,7 +788,7 @@ describe('endpoint unit test', () => {
request(app)
.put('/all-can-unpublish')
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
.set('authorization', buildToken(TOKEN_BEARER, token))
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token))
.send(JSON.stringify(_.assign({}, publishMetadata, {
name: 'all-can-unpublish'
})))
@ -768,7 +805,7 @@ describe('endpoint unit test', () => {
request(app)
.del('/all-can-unpublish/-rev/4-6abcdb4efd41a576')
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
.set('authorization', buildToken(TOKEN_BEARER, token))
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token))
.expect(HTTP_STATUS.CREATED)
.end(function(err, res) {
expect(err).toBeNull();

View file

@ -0,0 +1,24 @@
class FilterPlugin {
constructor(config) {
this._config = config;
}
filter_metadata(pkg) {
return new Promise((resolve, reject) => {
// We use this to test what happens when a filter rejects
if(pkg.name === 'trigger-filter-failure') {
reject(new Error('Example filter failure'));
return;
}
// 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
delete pkg.versions[this._config.version];
}
resolve(pkg);
}
);
}
}
exports.default = FilterPlugin;

View file

@ -1,8 +1,8 @@
/**
* @prettier
*/
import { addVersion, uploadPackageTarball, removeTarball, unPublishPackage, publishPackage } from '../../../src/api/endpoint/api/publish';
import { HTTP_STATUS, API_ERROR } from '../../../src/lib/constants';
import { addVersion, uploadPackageTarball, removeTarball, unPublishPackage, publishPackage } from '../../../../src/api/endpoint/api/publish';
import { HTTP_STATUS, API_ERROR } from '../../../../src/lib/constants';
const REVISION_MOCK = '15-e53a77096b0ee33e';

View file

@ -0,0 +1,41 @@
// ensure that all arguments are validated
import path from 'path';
import fs from 'fs';
/**
* Validate.
app.param('package', validate_pkg);
app.param('filename', validate_name);
app.param('tag', validate_name);
app.param('version', validate_name);
app.param('revision', validate_name);
app.param('token', validate_name);
*/
describe('api endpoint app.param()', () => {
const file = '../endpoint/index.js';
let m;
const requirePath = path.normalize(path.join(__dirname + '/../../../../src/api/web/', file));
const source = fs.readFileSync(requirePath, 'utf8');
const very_scary_regexp = /\n\s*app\.(\w+)\s*\(\s*(("[^"]*")|('[^']*'))\s*,/g;
const appParams = {};
while ((m = very_scary_regexp.exec(source)) != null) {
if (m[1] === 'set') continue;
let inner = m[2].slice(1, m[2].length-1);
var t;
inner.split('/').forEach(function(x) {
t = x.match(/^:([^?:]*)\??$/);
if (m[1] === 'param') {
appParams[x] = 'ok';
} else if (t) {
appParams[t[1]] = appParams[t[1]] || m[0].trim();
}
});
}
test.each(Object.keys(appParams))('should validate ":%s"', (param) => {
expect(appParams[param]).toEqual('ok');
});
});

View file

@ -1,25 +1,25 @@
// @flow
import _ from 'lodash';
import Auth from '../../../src/lib/auth';
import {CHARACTER_ENCODING} from '../../../src/lib/constants';
import Auth from '../../../../src/lib/auth';
import {CHARACTER_ENCODING, TOKEN_BEARER} from '../../../../src/lib/constants';
// $FlowFixMe
import configExample from '../partials/config/index';
import AppConfig from '../../../src/lib/config';
import {setup} from '../../../src/lib/logger';
import configExample from '../../partials/config';
import AppConfig from '../../../../src/lib/config';
import {setup} from '../../../../src/lib/logger';
import {convertPayloadToBase64, parseConfigFile} from '../../../src/lib/utils';
import {buildToken, convertPayloadToBase64, parseConfigFile} from '../../../../src/lib/utils';
import {
buildUserBuffer,
getApiToken,
getAuthenticatedMessage,
getMiddlewareCredentials,
getSecurity
} from '../../../src/lib/auth-utils';
import {aesDecrypt, verifyPayload} from '../../../src/lib/crypto-utils';
import {parseConfigurationFile} from '../__helper';
} from '../../../../src/lib/auth-utils';
import {aesDecrypt, verifyPayload} from '../../../../src/lib/crypto-utils';
import {parseConfigurationFile} from '../../__helper';
import type {IAuth, } from '../../../types/index';
import type {IAuth, } from '../../../../types';
import type {Config, Security, RemoteUser} from '@verdaccio/types';
setup([]);
@ -181,7 +181,7 @@ describe('Auth utilities', () => {
'test', 'test', secret, 'aesEncrypt', 'jwtEncrypt');
const config: Config = getConfig('security-legacy', secret);
const security: Security = getSecurity(config);
const credentials = getMiddlewareCredentials(security, 'BAD_SECRET', `Bearer ${token}`);
const credentials = getMiddlewareCredentials(security, 'BAD_SECRET', buildToken(TOKEN_BEARER, token));
expect(credentials).not.toBeDefined();
});
@ -191,7 +191,7 @@ describe('Auth utilities', () => {
'test', 'test', secret, 'aesEncrypt', 'jwtEncrypt');
const config: Config = getConfig('security-legacy', secret);
const security: Security = getSecurity(config);
const credentials = getMiddlewareCredentials(security, secret, `BAD_SCHEME ${token}`);
const credentials = getMiddlewareCredentials(security, secret, buildToken('BAD_SCHEME', token));
expect(credentials).not.toBeDefined();
});
@ -201,7 +201,7 @@ describe('Auth utilities', () => {
const auth: IAuth = new Auth(config);
const token = auth.aesEncrypt(new Buffer(`corruptedBuffer`)).toString('base64');
const security: Security = getSecurity(config);
const credentials = getMiddlewareCredentials(security, secret, `Bearer ${token}`);
const credentials = getMiddlewareCredentials(security, secret, buildToken(TOKEN_BEARER, token));
expect(credentials).not.toBeDefined();
});
});
@ -210,7 +210,7 @@ describe('Auth utilities', () => {
test('should return anonymous whether token is corrupted', () => {
const config: Config = getConfig('security-jwt', '12345');
const security: Security = getSecurity(config);
const credentials = getMiddlewareCredentials(security, '12345', 'Bearer fakeToken');
const credentials = getMiddlewareCredentials(security, '12345', buildToken(TOKEN_BEARER, 'fakeToken'));
expect(credentials).toBeDefined();
// $FlowFixMe
@ -224,7 +224,7 @@ describe('Auth utilities', () => {
test('should return anonymous whether token and scheme are corrupted', () => {
const config: Config = getConfig('security-jwt', '12345');
const security: Security = getSecurity(config);
const credentials = getMiddlewareCredentials(security, '12345', 'FakeScheme fakeToken');
const credentials = getMiddlewareCredentials(security, '12345', buildToken('FakeScheme', 'fakeToken'));
expect(credentials).not.toBeDefined();
});
@ -236,7 +236,7 @@ describe('Auth utilities', () => {
const token = await signCredentials('security-jwt',
user, 'secretTest', secret, 'jwtEncrypt', 'aesEncrypt');
const security: Security = getSecurity(config);
const credentials = getMiddlewareCredentials(security, secret, `Bearer ${token}`);
const credentials = getMiddlewareCredentials(security, secret, buildToken(TOKEN_BEARER, token));
expect(credentials).toBeDefined();
// $FlowFixMe
expect(credentials.name).toEqual(user);

View file

@ -5,16 +5,16 @@ import _ from 'lodash';
import path from 'path';
import rimraf from 'rimraf';
import endPointAPI from '../../../src/api/index';
import endPointAPI from '../../../../src/api';
import {HEADERS, HTTP_STATUS, HEADER_TYPE, TOKEN_BASIC, TOKEN_BEARER, API_ERROR} from '../../../src/lib/constants';
import {mockServer} from './mock';
import {DOMAIN_SERVERS} from '../../functional/config.functional';
import {buildToken, parseConfigFile} from '../../../src/lib/utils';
import {parseConfigurationFile} from '../__helper';
import {addUser, getPackage, loginUserToken} from './__api-helper';
import {setup} from '../../../src/lib/logger';
import {buildUserBuffer} from '../../../src/lib/auth-utils';
import {HEADERS, HTTP_STATUS, HEADER_TYPE, TOKEN_BEARER, TOKEN_BASIC, API_ERROR} from '../../../../src/lib/constants';
import {mockServer} from '../../__helper/mock';
import {DOMAIN_SERVERS} from '../../../functional/config.functional';
import {buildToken, parseConfigFile} from '../../../../src/lib/utils';
import {parseConfigurationFile} from '../../__helper';
import {addUser, getPackage, loginUserToken} from '../../__helper/api';
import {setup} from '../../../../src/lib/logger';
import {buildUserBuffer} from '../../../../src/lib/auth-utils';
setup([]);
const credentials = { name: 'JotaJWT', password: 'secretPass' };
@ -26,11 +26,13 @@ const parseConfigurationJWTFile = () => {
const FORBIDDEN_VUE: string = 'authorization required to access package vue';
describe('endpoint user auth JWT unit test', () => {
jest.setTimeout(20000);
let app;
let mockRegistry;
const FAKE_TOKEN: string = buildToken(TOKEN_BEARER, 'fake');
beforeAll(function(done) {
const store = path.join(__dirname, '../partials/store/test-jwt-storage');
const store = path.join(__dirname, '../../partials/store/test-jwt-storage');
const mockServerPort = 55546;
rimraf(store, async () => {
const confS = parseConfigFile(parseConfigurationJWTFile());
@ -44,7 +46,7 @@ describe('endpoint user auth JWT unit test', () => {
self_path: store,
auth: {
htpasswd: {
file: './test-jwt-storage/.htpasswd'
file: './test-jwt-storage/.htpasswd_jwt_auth'
}
}
});
@ -77,7 +79,7 @@ describe('endpoint user auth JWT unit test', () => {
expect(resp1.body).toBeDefined();
expect(resp1.body.name).toMatch('vue');
const [err2, resp2] = await getPackage(request(app), buildToken(TOKEN_BEARER, 'fake'), 'vue', HTTP_STATUS.UNAUTHORIZED);
const [err2, resp2] = await getPackage(request(app), FAKE_TOKEN, 'vue', HTTP_STATUS.UNAUTHORIZED);
expect(err2).toBeNull();
expect(resp2.statusCode).toBe(HTTP_STATUS.UNAUTHORIZED);
expect(resp2.body.error).toMatch(FORBIDDEN_VUE);
@ -95,7 +97,7 @@ describe('endpoint user auth JWT unit test', () => {
const token = buildUserBuffer(credentials.name, credentials.password).toString('base64');
request(app).put(`/-/user/org.couchdb.user:${credentials.name}/-rev/undefined`)
.send(credentials)
.set('authorization', buildToken(TOKEN_BASIC, token))
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BASIC, token))
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
.expect(HTTP_STATUS.CREATED)
.end(function(err, res) {
@ -108,7 +110,7 @@ describe('endpoint user auth JWT unit test', () => {
});
test('should fails on try to access with corrupted token', async (done) => {
const [err2, resp2] = await getPackage(request(app), buildToken(TOKEN_BEARER, 'fake'), 'vue', HTTP_STATUS.UNAUTHORIZED);
const [err2, resp2] = await getPackage(request(app), FAKE_TOKEN, 'vue', HTTP_STATUS.UNAUTHORIZED);
expect(err2).toBeNull();
expect(resp2.statusCode).toBe(HTTP_STATUS.UNAUTHORIZED);
expect(resp2.body.error).toMatch(FORBIDDEN_VUE);

View file

@ -5,13 +5,13 @@ import _ from 'lodash';
import path from 'path';
import rimraf from 'rimraf';
import endPointAPI from '../../../src/api/index';
import {mockServer} from './mock';
import {parseConfigFile} from '../../../src/lib/utils';
import {parseConfigurationFile} from '../__helper';
import {getNewToken, getProfile, postProfile} from './__api-helper';
import {setup} from '../../../src/lib/logger';
import {API_ERROR, HTTP_STATUS, SUPPORT_ERRORS} from '../../../src/lib/constants';
import endPointAPI from '../../../../src/api';
import {mockServer} from '../../__helper/mock';
import {parseConfigFile} from '../../../../src/lib/utils';
import {parseConfigurationFile} from '../../__helper';
import {getNewToken, getProfile, postProfile} from '../../__helper/api';
import {setup} from '../../../../src/lib/logger';
import {API_ERROR, HTTP_STATUS, SUPPORT_ERRORS} from '../../../../src/lib/constants';
setup([]);
@ -25,7 +25,7 @@ describe('endpoint user profile', () => {
let mockRegistry;
beforeAll(function(done) {
const store = path.join(__dirname, '../partials/store/test-profile-storage');
const store = path.join(__dirname, '../../partials/store/test-profile-storage');
const mockServerPort = 55544;
rimraf(store, async () => {
const parsedConfig = parseConfigFile(parseConfigurationProfile());
@ -33,7 +33,7 @@ describe('endpoint user profile', () => {
storage: store,
auth: {
htpasswd: {
file: './test-profile-storage/.htpasswd'
file: './test-profile-storage/.htpasswd-auth-profile'
}
},
self_path: store

View file

@ -1,15 +1,15 @@
import path from 'path';
import _ from 'lodash';
import startServer from '../../../src/index';
import config from '../partials/config/index';
import {DEFAULT_DOMAIN, DEFAULT_PORT, DEFAULT_PROTOCOL} from '../../../src/lib/constants';
import {getListListenAddresses} from '../../../src/lib/cli/utils';
import {parseConfigFile} from '../../../src/lib/utils';
import startServer from '../../../../src';
import config from '../../partials/config';
import {DEFAULT_DOMAIN, DEFAULT_PORT, DEFAULT_PROTOCOL} from '../../../../src/lib/constants';
import {getListListenAddresses} from '../../../../src/lib/cli/utils';
import {parseConfigFile} from '../../../../src/lib/utils';
const logger = require('../../../src/lib/logger');
const logger = require('../../../../src/lib/logger');
jest.mock('../../../src/lib/logger', () => ({
jest.mock('../../../../src/lib/logger', () => ({
setup: jest.fn(),
logger: {
child: jest.fn(),
@ -22,7 +22,7 @@ jest.mock('../../../src/lib/logger', () => ({
describe('startServer via API', () => {
const parseConfigurationFile = (name) => {
return parseConfigFile(path.join(__dirname, `../partials/config/yaml/${name}.yaml`));
return parseConfigFile(path.join(__dirname, `../../partials/config/yaml/${name}.yaml`));
};
describe('startServer launcher', () => {

View file

@ -1,27 +1,12 @@
import _ from 'lodash';
import {parseAddress as parse} from '../../../src/lib/utils';
import {DEFAULT_DOMAIN, DEFAULT_PORT} from '../../../src/lib/constants';
import {parseAddress as parse} from '../../../../src/lib/utils';
import {DEFAULT_DOMAIN, DEFAULT_PORT} from '../../../../src/lib/constants';
describe('Parse listen address', () => {
function addTest(uri, proto, host, port) {
test(`should parse ${uri}`, () => {
const parsed = parse(uri);
const useCases = [];
if (_.isNull(proto)) {
expect(parsed).toBeNull();
} else if (port) {
expect(parsed).toEqual({
proto,
host,
port,
});
} else {
expect(parsed).toEqual({
proto,
path: host,
});
}
});
function addTest(uri, proto, host, port) {
useCases.push([uri, proto, host, port]);
}
addTest(DEFAULT_PORT, 'http', DEFAULT_DOMAIN, DEFAULT_PORT);
@ -44,4 +29,23 @@ describe('Parse listen address', () => {
addTest('blah://4873', null);
addTest('https://blah:4873///', null);
addTest('unix:1234', 'http', 'unix', '1234'); // not unix socket
test.each(useCases)(`should parse (%s - %s - %s - %s)`, (uri, proto, host, port) => {
const parsed = parse(uri);
if (_.isNull(proto)) {
expect(parsed).toBeNull();
} else if (port) {
expect(parsed).toEqual({
proto,
host,
port,
});
} else {
expect(parsed).toEqual({
proto,
path: host,
});
}
});
});

View file

@ -1,12 +1,17 @@
import path from 'path';
import _ from 'lodash';
import Config from '../../../src/lib/config';
import {parseConfigFile} from '../../../src/lib/utils';
import {DEFAULT_REGISTRY, DEFAULT_UPLINK, ROLES, WEB_TITLE} from '../../../src/lib/constants';
import Config from '../../../../src/lib/config';
import {parseConfigFile} from '../../../../src/lib/utils';
import {DEFAULT_REGISTRY, DEFAULT_UPLINK, ROLES, WEB_TITLE} from '../../../../src/lib/constants';
const resolveConf = (conf) => path.join(__dirname, `../../../conf/${conf}.yaml`);
require('../../../src/lib/logger').setup([]);
const resolveConf = (conf) => {
const { name, ext } = path.parse(conf);
return path.join(__dirname, `../../../../conf/${name}${ext.startsWith('.') ? ext : '.yaml'}`);
};
require('../../../../src/lib/logger').setup([]);
const checkDefaultUplink = (config) => {
expect(_.isObject(config.uplinks[DEFAULT_UPLINK])).toBeTruthy();

View file

@ -1,16 +1,16 @@
// @flow
import {parseConfigurationFile} from '../__helper';
import {parseConfigFile} from '../../../src/lib/utils';
import {notify} from '../../../src/lib/notify';
import {parseConfigurationFile} from '../../__helper';
import {parseConfigFile} from '../../../../src/lib/utils';
import {notify} from '../../../../src/lib/notify';
import {notifyRequest} from '../../../src/lib/notify/notify-request';
import {notifyRequest} from '../../../../src/lib/notify/notify-request';
jest.mock('./../../../src/lib/notify/notify-request', () => ({
jest.mock('./../../../../src/lib/notify/notify-request', () => ({
notifyRequest: jest.fn((options, content) => Promise.resolve([options, content]))
}));
require('../../../src/lib/logger').setup([]);
require('../../../../src/lib/logger').setup([]);
const parseConfigurationNotifyFile = (name) => {
return parseConfigurationFile(`notify/${name}`);
@ -21,7 +21,7 @@ const packagePatternNotificationConfig = parseConfigFile(parseConfigurationNotif
const multiNotificationConfig = parseConfigFile(parseConfigurationNotifyFile('multiple.notify'));
describe('Notify', () => {
describe('Notifications:: Notify', () => {
beforeEach(() => {
jest.clearAllMocks();

View file

@ -2,7 +2,7 @@
* @prettier
*/
import { HTTP_STATUS, API_ERROR } from '../../../src/lib/constants';
import { HTTP_STATUS, API_ERROR } from '../../../../src/lib/constants';
/**
* Mocks Logger Service
@ -14,7 +14,7 @@ const logger = {
info: jest.fn(),
},
};
jest.doMock('../../../src/lib/logger', () => logger);
jest.doMock('../../../../src/lib/logger', () => logger);
/**
* Test Data
@ -24,7 +24,7 @@ const options = {
};
const content = 'Verdaccio@x.x.x successfully published';
describe('notifyRequest', () => {
describe('Notifications:: notifyRequest', () => {
beforeEach(() => {
jest.resetModules();
});
@ -40,7 +40,7 @@ describe('notifyRequest', () => {
resolver(error, response);
});
const notification = require('../../../src/lib/notify/notify-request');
const notification = require('../../../../src/lib/notify/notify-request');
const args = [{ errorMessage: 'bad data' }, 'notify service has thrown an error: @{errorMessage}'];
await expect(notification.notifyRequest(options, content)).rejects.toEqual(API_ERROR.BAD_DATA);
@ -57,7 +57,7 @@ describe('notifyRequest', () => {
resolver(null, response);
});
const notification = require('../../../src/lib/notify/notify-request');
const notification = require('../../../../src/lib/notify/notify-request');
const args = [{ errorMessage: 'bad data' }, 'notify service has thrown an error: @{errorMessage}'];
await expect(notification.notifyRequest(options, content)).rejects.toEqual(API_ERROR.BAD_DATA);
@ -74,7 +74,7 @@ describe('notifyRequest', () => {
resolver(null, response, response.body);
});
const notification = require('../../../src/lib/notify/notify-request');
const notification = require('../../../../src/lib/notify/notify-request');
const infoArgs = [{ content }, 'A notification has been shipped: @{content}'];
const debugArgs = [{ body: 'Successfully delivered' }, ' body: @{body}'];
@ -92,7 +92,7 @@ describe('notifyRequest', () => {
resolver(null, response);
});
const notification = require('../../../src/lib/notify/notify-request');
const notification = require('../../../../src/lib/notify/notify-request');
const infoArgs = [{ content }, 'A notification has been shipped: @{content}'];
await expect(notification.notifyRequest(options, content)).rejects.toThrow('body is missing');

View file

@ -1,14 +1,14 @@
import _ from 'lodash';
// @flow
import Auth from '../../../src/lib/auth';
import Auth from '../../../../src/lib/auth';
// $FlowFixMe
import _configExample from '../partials/config/index';
import _configExample from '../../partials/config';
// $FlowFixMe
import _configPlugins from '../partials/config/plugin';
import AppConfig from '../../../src/lib/config';
import {setup} from '../../../src/lib/logger';
import _configPlugins from './helper/plugin';
import AppConfig from '../../../../src/lib/config';
import {setup} from '../../../../src/lib/logger';
import type {IAuth} from '../../../types/index';
import type {IAuth} from '../../../../types';
import type {Config} from '@verdaccio/types';
setup([]);

View file

@ -0,0 +1,12 @@
import path from 'path';
import config from '../../../partials/config';
const authProfileConf = {
...config(),
auth: {
[`${path.join(__dirname, '../../../partials/plugin/authenticate')}`]: { }
}
};
export default authProfileConf;

View file

@ -1,12 +1,12 @@
import path from 'path';
import loadPlugin from '../../../src/lib/plugin-loader';
import logger from '../../../src/lib/logger';
import loadPlugin from '../../../../src/lib/plugin-loader';
import logger from '../../../../src/lib/logger';
logger.setup([]);
describe('plugin loader', () => {
const relativePath = './partials/test-plugin-storage';
const relativePath = path.join(__dirname, './partials/test-plugin-storage');
const buildConf = name => {
return {
self_path: path.join(__dirname, './'),

View file

@ -1,10 +1,10 @@
import Search from '../../../src/lib/search';
import Config from '../../../src/lib/config';
import Storage from '../../../src/lib/storage';
import buildConfig from '../partials/config/index';
import Search from '../../../../src/lib/search';
import Config from '../../../../src/lib/config';
import Storage from '../../../../src/lib/storage';
import buildConfig from '../../partials/config';
require('../../../src/lib/logger').setup([]);
require('../../../../src/lib/logger').setup([]);
let packages = [
{

View file

@ -3,20 +3,20 @@
import rimRaf from 'rimraf';
import path from 'path';
import LocalStorage from '../../../src/lib/local-storage';
import AppConfig from '../../../src/lib/config';
import LocalStorage from '../../../../src/lib/local-storage';
import AppConfig from '../../../../src/lib/config';
// $FlowFixMe
import configExample from '../partials/config/index';
import Logger, {setup} from '../../../src/lib/logger';
import {readFile} from '../../functional/lib/test.utils';
import {generatePackageTemplate} from '../../../src/lib/storage-utils';
import {generateNewVersion} from '../../lib/utils-test';
import configExample from '../../partials/config';
import Logger, {setup} from '../../../../src/lib/logger';
import {readFile} from '../../../functional/lib/test.utils';
import {generatePackageTemplate} from '../../../../src/lib/storage-utils';
import {generateNewVersion} from '../../../lib/utils-test';
const readMetadata = (fileName: string = 'metadata') => readFile(`../../unit/partials/${fileName}`);
import type {Config, MergeTags} from '@verdaccio/types';
import type {IStorage} from '../../../types/index';
import { API_ERROR, HTTP_STATUS, DIST_TAGS} from '../../../src/lib/constants';
import type {IStorage} from '../../../../types';
import { API_ERROR, HTTP_STATUS, DIST_TAGS} from '../../../../src/lib/constants';
setup([]);

View file

@ -1,8 +1,8 @@
let assert = require('assert');
let semverSort = require('../../../src/lib/utils').semverSort;
import {mergeVersions} from '../../../src/lib/metadata-utils';
let semverSort = require('../../../../src/lib/utils').semverSort;
import {mergeVersions} from '../../../../src/lib/metadata-utils';
require('../../../src/lib/logger').setup([]);
require('../../../../src/lib/logger').setup([]);
describe('Storage._merge_versions versions', () => {

View file

@ -1,8 +1,8 @@
// @flow
import {normalizePackage, mergeUplinkTimeIntoLocal} from "../../../src/lib/storage-utils";
import { STORAGE, DIST_TAGS } from '../../../src/lib/constants';
import {readFile} from "../../functional/lib/test.utils";
import {normalizePackage, mergeUplinkTimeIntoLocal} from "../../../../src/lib/storage-utils";
import { STORAGE, DIST_TAGS } from '../../../../src/lib/constants';
import {readFile} from "../../../functional/lib/test.utils";
import type {Package} from '@verdaccio/types';

View file

@ -4,20 +4,20 @@ import path from 'path';
import fs from 'fs';
import rimraf from 'rimraf';
// $FlowFixMe
import configExample from '../partials/config/index';
import AppConfig from '../../../src/lib/config';
import Storage from '../../../src/lib/storage';
import {setup} from '../../../src/lib/logger';
import configExample from '../../partials/config';
import AppConfig from '../../../../src/lib/config';
import Storage from '../../../../src/lib/storage';
import {setup} from '../../../../src/lib/logger';
import type {Config} from '@verdaccio/types';
import type {IStorageHandler} from '../../../types/index';
import {API_ERROR, HTTP_STATUS} from '../../../src/lib/constants';
import {mockServer} from './mock';
import {DOMAIN_SERVERS} from '../../functional/config.functional';
import type {IStorageHandler} from '../../../../types';
import {API_ERROR, HTTP_STATUS} from '../../../../src/lib/constants';
import {mockServer} from '../../__helper/mock';
import {DOMAIN_SERVERS} from '../../../functional/config.functional';
setup([]);
const storagePath = path.join(__dirname, '../partials/store/test-storage-store.spec');
const storagePath = path.join(__dirname, '../../partials/store/test-storage-store.spec');
const mockServerPort: number = 55548;
const generateStorage = async function(port = mockServerPort) {
const storageConfig = configExample({
@ -99,7 +99,7 @@ describe('StorageTest', () => {
test('should not touch if the package exists and has no uplinks', async (done) => {
const storage: IStorageHandler = await generateStorage();
const metadataSource = path.join(__dirname, '../partials/metadata');
const metadataSource = path.join(__dirname, '../../partials/metadata');
const metadataPath = path.join(storagePath, 'npm_test/package.json');
fs.mkdirSync(path.join(storagePath, 'npm_test'));

View file

@ -1,7 +1,7 @@
import ProxyStorage from '../../../src/lib/up-storage';
import {ERROR_CODE, TOKEN_BASIC, TOKEN_BEARER, DEFAULT_REGISTRY} from "../../../src/lib/constants";
import {buildToken} from "../../../src/lib/utils";
import {setup} from '../../../src/lib/logger';
import ProxyStorage from '../../../../src/lib/up-storage';
import {ERROR_CODE, TOKEN_BASIC, TOKEN_BEARER, DEFAULT_REGISTRY, HEADERS} from "../../../../src/lib/constants";
import {buildToken} from "../../../../src/lib/utils";
import {setup} from '../../../../src/lib/logger';
setup([]);
@ -22,12 +22,12 @@ function setHeaders(config, headers) {
});
}
describe('uplink auth test', () => {
describe('uplink headers auth test', () => {
test('if set headers empty should return default headers', () => {
const headers = setHeaders();
const keys = Object.keys(headers);
const keysExpected = ['Accept', 'Accept-Encoding', 'User-Agent'];
const keysExpected = [HEADERS.ACCEPT, HEADERS.ACCEPT_ENCODING, HEADERS.USER_AGENT];
expect(keys).toEqual(keysExpected);
expect(keys).toHaveLength(3);
@ -47,11 +47,11 @@ describe('uplink auth test', () => {
test('if assigns the header authorization', () => {
const headers = setHeaders({}, {
'authorization': buildToken(TOKEN_BASIC, 'Zm9vX2Jhcg==')
[HEADERS.AUTHORIZATION]: buildToken(TOKEN_BASIC, 'Zm9vX2Jhcg==')
});
expect(Object.keys(headers)).toHaveLength(4);
expect(headers['authorization']).toEqual(buildToken(TOKEN_BASIC, 'Zm9vX2Jhcg=='));
expect(headers[HEADERS.AUTHORIZATION]).toEqual(buildToken(TOKEN_BASIC, 'Zm9vX2Jhcg=='));
});
test(
@ -63,10 +63,10 @@ describe('uplink auth test', () => {
token: 'tokenBearer'
}
}, {
'authorization': buildToken(TOKEN_BASIC, 'tokenBasic')
[HEADERS.AUTHORIZATION]: buildToken(TOKEN_BASIC, 'tokenBasic')
});
expect(headers['authorization']).toEqual(buildToken(TOKEN_BASIC, 'tokenBasic'));
expect(headers[HEADERS.AUTHORIZATION]).toEqual(buildToken(TOKEN_BASIC, 'tokenBasic'));
}
);
@ -79,7 +79,7 @@ describe('uplink auth test', () => {
});
expect(Object.keys(headers)).toHaveLength(4);
expect(headers['authorization']).toEqual(buildToken(TOKEN_BASIC, 'Zm9vX2Jhcg=='));
expect(headers[HEADERS.AUTHORIZATION]).toEqual(buildToken(TOKEN_BASIC, 'Zm9vX2Jhcg=='));
});
test('set type auth bearer', () => {
@ -91,7 +91,7 @@ describe('uplink auth test', () => {
});
expect(Object.keys(headers)).toHaveLength(4);
expect(headers['authorization']).toEqual(buildToken(TOKEN_BEARER, 'Zm9vX2Jhcf==='));
expect(headers[HEADERS.AUTHORIZATION]).toEqual(buildToken(TOKEN_BEARER, 'Zm9vX2Jhcf==='));
});
test('set auth type invalid', () => {
@ -117,7 +117,7 @@ describe('uplink auth test', () => {
}
});
expect(headers['authorization']).toBe(`${TOKEN_BEARER} myToken`);
expect(headers[HEADERS.AUTHORIZATION]).toBe(buildToken(TOKEN_BEARER, 'myToken'));
delete process.env.NPM_TOKEN;
});
@ -130,7 +130,7 @@ describe('uplink auth test', () => {
}
});
expect(headers['authorization']).toBe(buildToken(TOKEN_BASIC, 'myTokenTest'));
expect(headers[HEADERS.AUTHORIZATION]).toBe(buildToken(TOKEN_BASIC, 'myTokenTest'));
delete process.env.NPM_TOKEN_TEST;
});

View file

@ -1,15 +1,17 @@
import Storage from '../../../src/lib/up-storage';
import Storage from '../../../../src/lib/up-storage';
require('../../../src/lib/logger').setup([]);
require('../../../../src/lib/logger').setup([]);
function setupProxy(host, config, mainconfig) {
function setupProxy(host, config, mainConfig) {
config.url = host;
return new Storage(config, mainconfig);
return new Storage(config, mainConfig);
}
describe('Use proxy', () => {
test('should work fine without proxy', () => {
let x = setupProxy('http://x/x', {}, {});
expect(x.proxy).toEqual(undefined);
});
@ -20,6 +22,7 @@ describe('Use proxy', () => {
test('no_proxy is invalid', () => {
let x = setupProxy('http://x/x', {http_proxy: '123', no_proxy: false}, {});
expect(x.proxy).toEqual('123');
x = setupProxy('http://x/x', {http_proxy: '123', no_proxy: null}, {});
expect(x.proxy).toEqual('123');
@ -31,16 +34,19 @@ describe('Use proxy', () => {
test('no_proxy - simple/include', () => {
let x = setupProxy('http://localhost', {http_proxy: '123'}, {no_proxy: 'localhost'});
expect(x.proxy).toEqual(undefined);
});
test('no_proxy - simple/not', () => {
let x = setupProxy('http://localhost', {http_proxy: '123'}, {no_proxy: 'blah'});
expect(x.proxy).toEqual('123');
});
test('no_proxy - various, single string', () => {
let x = setupProxy('http://blahblah', {http_proxy: '123'}, {no_proxy: 'blah'});
expect(x.proxy).toEqual('123');
x = setupProxy('http://blah.blah', {}, {http_proxy: '123', no_proxy: 'blah'});
expect(x.proxy).toEqual(undefined);
@ -56,6 +62,7 @@ describe('Use proxy', () => {
test('no_proxy - various, array', () => {
let x = setupProxy('http://blahblah', {http_proxy: '123'}, {no_proxy: 'foo,bar,blah'});
expect(x.proxy).toEqual('123');
x = setupProxy('http://blah.blah', {http_proxy: '123'}, {no_proxy: 'foo,bar,blah'});
expect(x.proxy).toEqual(undefined);
@ -71,6 +78,7 @@ describe('Use proxy', () => {
test('no_proxy - hostport', () => {
let x = setupProxy('http://localhost:80', {http_proxy: '123'}, {no_proxy: 'localhost'});
expect(x.proxy).toEqual(undefined);
x = setupProxy('http://localhost:8080', {http_proxy: '123'}, {no_proxy: 'localhost'});
expect(x.proxy).toEqual(undefined);
@ -78,6 +86,7 @@ describe('Use proxy', () => {
test('no_proxy - secure', () => {
let x = setupProxy('https://something', {http_proxy: '123'}, {});
expect(x.proxy).toEqual(undefined);
x = setupProxy('https://something', {https_proxy: '123'}, {});
expect(x.proxy).toEqual('123');

View file

@ -1,16 +1,16 @@
// @flow
import _ from 'lodash';
import ProxyStorage from '../../../src/lib/up-storage';
import AppConfig from '../../../src/lib/config';
import ProxyStorage from '../../../../src/lib/up-storage';
import AppConfig from '../../../../src/lib/config';
// $FlowFixMe
import configExample from '../partials/config/index';
import {setup} from '../../../src/lib/logger';
import configExample from '../../partials/config';
import {setup} from '../../../../src/lib/logger';
import type {Config, UpLinkConf} from '@verdaccio/types';
import type {IProxy} from '../../../types/index';
import {API_ERROR, HTTP_STATUS} from "../../../src/lib/constants";
import {mockServer} from './mock';
import {DOMAIN_SERVERS} from '../../functional/config.functional';
import type {IProxy} from '../../../../types';
import {API_ERROR, HTTP_STATUS} from "../../../../src/lib/constants";
import {mockServer} from '../../__helper/mock';
import {DOMAIN_SERVERS} from '../../../functional/config.functional';
setup([]);

View file

@ -13,13 +13,13 @@ import _ from 'lodash';
import path from 'path';
import rimraf from 'rimraf';
import endPointAPI from '../../../src/api/index';
import {mockServer} from './mock';
import {DOMAIN_SERVERS} from '../../functional/config.functional';
import {parseConfigFile} from '../../../src/lib/utils';
import {parseConfigurationFile} from '../__helper';
import {addUser} from './__api-helper';
import {setup} from '../../../src/lib/logger';
import endPointAPI from '../../../../src/api/index';
import {mockServer} from '../../__helper/mock';
import {DOMAIN_SERVERS} from '../../../functional/config.functional';
import {parseConfigFile} from '../../../../src/lib/utils';
import {parseConfigurationFile} from '../../__helper';
import {addUser} from '../../__helper/api';
import {setup} from '../../../../src/lib/logger';
// we must start logging without output
setup([]);
@ -37,7 +37,7 @@ describe('endpoint example unit test', () => {
beforeAll(function(done) {
// 1. We create a route for a custom storage folder for this test
const store = path.join(__dirname, '../partials/store/test-jwt-storage');
const store = path.join(__dirname, '../../partials/store/test-template-storage');
// 2. The port must be unique (at this point this is not automated, need to be checked manually)
const mockServerPort = 55546;
// 3. Use rimraf to clean the state each time you run the test

View file

@ -2,20 +2,23 @@
import path from 'path';
import _ from 'lodash';
import {spliceURL} from '../../../src/utils/string';
import {parseConfigFile} from '../../../src/lib/utils';
import {spliceURL} from '../../../../src/utils/string';
import {parseConfigFile} from '../../../../src/lib/utils';
import {
getMatchedPackagesSpec,
hasProxyTo,
normalisePackageAccess, sanityCheckUplinksProps,
uplinkSanityCheck
} from '../../../src/lib/config-utils';
import {PACKAGE_ACCESS, ROLES} from '../../../src/lib/constants';
} from '../../../../src/lib/config-utils';
import {PACKAGE_ACCESS, ROLES} from '../../../../src/lib/constants';
describe('Config Utilities', () => {
const parseConfigurationFile = (name) => {
return path.join(__dirname, `../partials/config/yaml/${name}.yaml`);
const parseConfigurationFile = (conf) => {
const { name, ext } = path.parse(conf);
const format = ext.startsWith('.') ? ext.substring(1) : 'yaml';
return path.join(__dirname, `../../partials/config/${format}/${name}.${format}`);
};
describe('uplinkSanityCheck', () => {
@ -265,4 +268,44 @@ describe('Config Utilities', () => {
expect(url).toMatch('/-/static/logo.png');
});
});
describe('JSON', () => {
test('parse default.json', () => {
const config = parseConfigFile(parseConfigurationFile('default.json'));
expect(config.storage).toBeDefined();
});
test('parse invalid.json', () => {
expect(function ( ) {
parseConfigFile(parseConfigurationFile('invalid.json'));
}).toThrow(/Error/);
});
test('parse not-exists.json', () => {
expect(function ( ) {
parseConfigFile(parseConfigurationFile('not-exists.json'));
}).toThrow(/Error/);
});
});
describe('JavaScript', () => {
test('parse default.js', () => {
const config = parseConfigFile(parseConfigurationFile('default.js'));
expect(config.storage).toBeDefined();
});
test('parse invalid.js', () => {
expect(function ( ) {
parseConfigFile(parseConfigurationFile('invalid.js'));
}).toThrow(/Error/);
});
test('parse not-exists.js', () => {
expect(function ( ) {
parseConfigFile(parseConfigurationFile('not-exists.js'));
}).toThrow(/Error/);
});
});
});

View file

@ -1,5 +1,5 @@
let assert = require('assert');
let parseInterval = require('../../../src/lib/utils').parseInterval;
let parseInterval = require('../../../../src/lib/utils').parseInterval;
describe('Parse interval', () => {
function add_test(str, res) {

View file

@ -1,7 +1,7 @@
let assert = require('assert');
let tag_version = require('../../../src/lib/utils').tagVersion;
let tag_version = require('../../../../src/lib/utils').tagVersion;
require('../../../src/lib/logger').setup([]);
require('../../../../src/lib/logger').setup([]);
describe('tag_version', () => {
test('add new one', () => {

View file

@ -1,6 +1,6 @@
// @flow
import {generateGravatarUrl, GENERIC_AVATAR } from '../../../src/utils/user';
import { spliceURL } from '../../../src/utils/string';
import {generateGravatarUrl, GENERIC_AVATAR } from '../../../../src/utils/user';
import { spliceURL } from '../../../../src/utils/string';
import {
validateName,
convertDistRemoteToLocalTarballUrls,
@ -16,10 +16,10 @@ import {
sortByName,
formatAuthor,
isHTTPProtocol,
} from '../../../src/lib/utils';
import { DIST_TAGS, DEFAULT_USER } from '../../../src/lib/constants';
import Logger, { setup } from '../../../src/lib/logger';
import { readFile } from '../../functional/lib/test.utils';
} from '../../../../src/lib/utils';
import { DIST_TAGS, DEFAULT_USER } from '../../../../src/lib/constants';
import Logger, { setup } from '../../../../src/lib/logger';
import { readFile } from '../../../functional/lib/test.utils';
const readmeFile = (fileName: string = 'markdown.md') =>
readFile(`../../unit/partials/readme/${fileName}`);

View file

@ -2,17 +2,17 @@ import request from 'supertest';
import path from 'path';
import rimraf from 'rimraf';
import configDefault from '../partials/config/index';
import publishMetadata from '../partials/publish-api';
import forbiddenPlace from '../partials/forbidden-place';
import endPointAPI from '../../../src/api/index';
import configDefault from '../../partials/config';
import publishMetadata from '../../partials/publish-api';
import forbiddenPlace from '../../partials/forbidden-place';
import endPointAPI from '../../../../src/api';
import { HEADERS, API_ERROR, HTTP_STATUS, HEADER_TYPE, DIST_TAGS} from '../../../src/lib/constants';
import {DOMAIN_SERVERS} from '../../functional/config.functional';
import {mockServer} from './mock';
import {addUser} from './__api-helper';
import { HEADERS, API_ERROR, HTTP_STATUS, HEADER_TYPE, DIST_TAGS} from '../../../../src/lib/constants';
import {DOMAIN_SERVERS} from '../../../functional/config.functional';
import {mockServer} from '../../__helper/mock';
import {addUser} from '../../__helper/api';
require('../../../src/lib/logger').setup([]);
require('../../../../src/lib/logger').setup([]);
const credentials = { name: 'user-web', password: 'secretPass' };
describe('endpoint web unit test', () => {
@ -20,16 +20,16 @@ describe('endpoint web unit test', () => {
let mockRegistry;
beforeAll(function(done) {
const store = path.join(__dirname, '../store/test-storage-web');
const store = path.join(__dirname, '../../partials/store/web-api-storage');
const mockServerPort = 55544;
rimraf(store, async () => {
const configForTest = configDefault({
auth: {
htpasswd: {
file: './test-storage-web/.htpasswd'
file: './web-api-storage/.htpasswd-web-api'
}
},
storage: path.join(__dirname, '../store/test-storage-web'),
storage: store,
uplinks: {
npmjs: {
url: `http://${DOMAIN_SERVERS}:${mockServerPort}`

View file

@ -0,0 +1,15 @@
module.exports = { storage: './storage_default_storage',
uplinks: { npmjs: { url: 'http://localhost:4873/' } },
packages:
{ '@*/*': { access: '$all', publish: '$all', proxy: 'npmjs' },
'forbidden-place': { access: 'nobody', publish: '$all' },
react: { access: '$all', publish: '$all', proxy: 'npmjs' },
'corrupted-package': { access: '$all', publish: '$all', proxy: 'npmjs' },
jquery: { access: '$all', publish: '$all', proxy: 'npmjs' },
'auth-package': { access: '$authenticated', publish: '$authenticated' },
vue:
{ access: '$authenticated',
publish: '$authenticated',
proxy: 'npmjs' },
'*': { access: '$all', publish: '$all', proxy: 'npmjs' } },
logs: [ { type: 'stdout', format: 'pretty', level: 'warn' } ] };

View file

@ -0,0 +1 @@
module.exports = {;

View file

@ -0,0 +1,55 @@
{
"storage": "./storage_default_storage",
"uplinks": {
"npmjs": {
"url": "http://localhost:4873/"
}
},
"packages": {
"@*/*": {
"access": "$all",
"publish": "$all",
"proxy": "npmjs"
},
"forbidden-place": {
"access": "nobody",
"publish": "$all"
},
"react": {
"access": "$all",
"publish": "$all",
"proxy": "npmjs"
},
"corrupted-package": {
"access": "$all",
"publish": "$all",
"proxy": "npmjs"
},
"jquery": {
"access": "$all",
"publish": "$all",
"proxy": "npmjs"
},
"auth-package": {
"access": "$authenticated",
"publish": "$authenticated"
},
"vue": {
"access": "$authenticated",
"publish": "$authenticated",
"proxy": "npmjs"
},
"*": {
"access": "$all",
"publish": "$all",
"proxy": "npmjs"
}
},
"logs": [
{
"type": "stdout",
"format": "pretty",
"level": "warn"
}
]
}

View file

@ -0,0 +1 @@
{

View file

@ -1,10 +0,0 @@
import path from 'path';
import config from './index';
module.exports = {
...config(),
auth: {
[`${path.join(__dirname, '../plugin/authenticate')}`]: { }
}
};

View file

@ -1,2 +1,2 @@
server:
foo: "bar"
foo: 'bar'

View file

@ -0,0 +1,87 @@
{
"_id": "npm_test",
"name": "npm_test",
"description": "",
"dist-tags": {
"latest": "1.0.0"
},
"versions": {
"1.0.0": {
"name": "npm_test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"test": "^1.4.0"
},
"devDependencies": {
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
],
"author": "",
"license": "ISC",
"readme": "ERROR: No README data found!",
"_id": "npm_test@1.0.0",
"_npmVersion": "5.5.1",
"_nodeVersion": "9.3.0",
"_npmUser": {
},
"dist": {
"integrity": "sha512-tfzM1OFjWwg2d2Wke\/DV6icjeTZUVOZYLkbf8wmONRSAgMovL\/F+zyI24OhTtWyOXd1Kbj2YUMBvLpmpAjv8zg==",
"shasum": "3e4e6bd5097b295e520b947c9be3259a9509a673",
"tarball": "http:\/\/localhost:4873\/npm_test\/-\/npm_test-1.0.0.tgz"
}
},
"2.0.0": {
"name": "npm_test",
"version": "2.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"test": "^2.4.0"
},
"devDependencies": {
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
],
"author": "",
"license": "ISC",
"readme": "ERROR: No README data found!",
"_id": "npm_test@2.0.0",
"_npmVersion": "5.5.1",
"_nodeVersion": "9.3.0",
"_npmUser": {
},
"dist": {
"integrity": "sha512-tzzM1OFjWwg2d2Wke\/DV6icjeTZUVOZYLkbf8wmONRSAgMovL\/F+zyI24OhTtWyOXd1Kbj2YUMBvLpmpAjv8zg==",
"shasum": "3a4e6bd5097b295e520b947c9be3259a9509a673",
"tarball": "http:\/\/localhost:4873\/npm_test\/-\/npm_test-2.0.0.tgz"
}
}
},
"readme": "ERROR: No README data found!",
"_attachments": {
"npm_test-1.0.0.tgz": {
"content_type": "application\/octet-stream",
"data": "H4sIAAAAAAAAE+2ST08CMRDFOe+nmPTAyawt7ELCVT149ihqmu4gI9I2bUGM4bvbbhGM4eYmxmR\/l6bvtW+mf6xUK\/mMlzaP5Ys3etAxnPNJVcE5PVHV0RPjkairsZiK0YALUU+mMOBdN3KOjQ\/SxVZ+m5PPAsfxn\/BRADAt18hmwDxpY0k+BfSBXSRni86T0ckUJS95Vhv0ypENByeLa0ntjHSDu\/iPvpZajIJWhD66qRwcC6Xlj6KsYm7U94cN2+sfe7KRS34LabuMCaiWBubsxjnjZqANJAO8RUULwmbOYDgE3FEAcSqzwvc345oUd\/\/QKnITlsadzvNKCrVv7+X27ooV++Kv36qnp6enSz4B8bhKUwAIAAA=",
"length": 281
},
"npm_test-2.0.0.tgz": {
"content_type": "application\/octet-stream",
"data": "H4sIAAAAAAAAE+2ST08CMRDFOe+nmPTAyawt7ELCVT149ihqmu4gI9I2bUGM4bvbbhGM4eYmxmR\/l6bvtW+mf6xUK\/mMlzaP5Ys3etAxnPNJVcE5PVHV0RPjkairsZiK0YALUU+mMOBdN3KOjQ\/SxVZ+m5PPAsfxn\/BRADAt18hmwDxpY0k+BfSBXSRni86T0ckUJS95Vhv0ypENByeLa0ntjHSDu\/iPvpZajIJWhD66qRwcC6Xlj6KsYm7U94cN2+sfe7KRS34LabuMCaiWBubsxjnjZqANJAO8RUULwmbOYDgE3FEAcSqzwvc345oUd\/\/QKnITlsadzvNKCrVv7+X27ooV++Kv36qnp6enSz4B8bhKUwAIAAA=",
"length": 281
}
}
}

206
yarn.lock
View file

@ -1464,10 +1464,10 @@
resolved "https://registry.verdaccio.org/@verdaccio%2fstreams/-/streams-2.0.0-beta.0.tgz#af8c7e673a3c368deacc8024c6f5671aa2ec32ac"
integrity sha512-EdVF6RP0abRNT0RfgLCsqLNv7FOpm+BpzMZoaQuQGHSBQRj7OTM8ft5mpbJ40rYVXKv6D8xyU0vUnoRl09ah6g==
"@verdaccio/types@5.0.0-beta.4":
version "5.0.0-beta.4"
resolved "https://registry.verdaccio.org/@verdaccio%2ftypes/-/types-5.0.0-beta.4.tgz#433a36bef5b3bbd31711c48071989ac35dc83e54"
integrity sha512-aPrCUrFMXo/ikgT/9YEAr5EDlH2gFJGfdrUra2ipQxV3SbNrRN95KxwwSDS+W+YKG0+rAIQKIxnx8hf6gEtePQ==
"@verdaccio/types@5.0.2":
version "5.0.2"
resolved "https://registry.verdaccio.org/@verdaccio%2ftypes/-/types-5.0.2.tgz#b9a00a1a7c4fb3f410a839b10417bc3201b10415"
integrity sha512-jjuBKxRcKTLcFNI1Ul1yquDLgYwNcuaTxYZdGK2XvN4e/BQ24WzBEnMW9LSZlWDZQgpINAD6qVuTT+albtdnXQ==
"@verdaccio/ui-theme@0.1.11":
version "0.1.11"
@ -2640,136 +2640,140 @@ content-type@~1.0.4:
resolved "https://registry.verdaccio.org/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
conventional-changelog-angular@^1.3.3:
conventional-changelog-angular@^1.3.3, conventional-changelog-angular@^1.6.6:
version "1.6.6"
resolved "https://registry.verdaccio.org/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz#b27f2b315c16d0a1f23eb181309d0e6a4698ea0f"
resolved "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz#b27f2b315c16d0a1f23eb181309d0e6a4698ea0f"
integrity sha512-suQnFSqCxRwyBxY68pYTsFkG0taIdinHLNEAX5ivtw8bCRnIgnpvcHmlR/yjUyZIrNPYAoXlY1WiEKWgSE4BNg==
dependencies:
compare-func "^1.3.1"
q "^1.5.1"
conventional-changelog-angular@^5.0.3:
version "5.0.3"
resolved "https://registry.verdaccio.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.3.tgz#299fdd43df5a1f095283ac16aeedfb0a682ecab0"
integrity sha512-YD1xzH7r9yXQte/HF9JBuEDfvjxxwDGGwZU1+ndanbY0oFgA+Po1T9JDSpPLdP0pZT6MhCAsdvFKC4TJ4MTJTA==
dependencies:
compare-func "^1.3.1"
q "^1.5.1"
conventional-changelog-atom@^2.0.1:
version "2.0.1"
resolved "https://registry.verdaccio.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.1.tgz#dc88ce650ffa9ceace805cbe70f88bfd0cb2c13a"
integrity sha512-9BniJa4gLwL20Sm7HWSNXd0gd9c5qo49gCi8nylLFpqAHhkFTj7NQfROq3f1VpffRtzfTQp4VKU5nxbe2v+eZQ==
conventional-changelog-atom@^0.2.8:
version "0.2.8"
resolved "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-0.2.8.tgz#8037693455990e3256f297320a45fa47ee553a14"
integrity sha512-8pPZqhMbrnltNBizjoDCb/Sz85KyUXNDQxuAEYAU5V/eHn0okMBVjqc8aHWYpHrytyZWvMGbayOlDv7i8kEf6g==
dependencies:
q "^1.5.1"
conventional-changelog-codemirror@^2.0.1:
version "2.0.1"
resolved "https://registry.verdaccio.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.1.tgz#acc046bc0971460939a0cc2d390e5eafc5eb30da"
integrity sha512-23kT5IZWa+oNoUaDUzVXMYn60MCdOygTA2I+UjnOMiYVhZgmVwNd6ri/yDlmQGXHqbKhNR5NoXdBzSOSGxsgIQ==
conventional-changelog-codemirror@^0.3.8:
version "0.3.8"
resolved "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-0.3.8.tgz#a1982c8291f4ee4d6f2f62817c6b2ecd2c4b7b47"
integrity sha512-3HFZKtBXTaUCHvz7ai6nk2+psRIkldDoNzCsom0egDtVmPsvvHZkzjynhdQyULfacRSsBTaiQ0ol6nBOL4dDiQ==
dependencies:
q "^1.5.1"
conventional-changelog-conventionalcommits@^1.1.1:
version "1.1.1"
resolved "https://registry.verdaccio.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-1.1.1.tgz#322351f6a0422876d89ec54491365695b073a709"
integrity sha512-21BcbiSfvYIon7sF80Rwn6vnfhaiuZUyHHFYr9Zz8H2B+O/3grud5TbEYpU1/SFXD5aD48IdSme/KkJl9wCsCw==
conventional-changelog-core@^2.0.11:
version "2.0.11"
resolved "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-2.0.11.tgz#19b5fbd55a9697773ed6661f4e32030ed7e30287"
integrity sha512-HvTE6RlqeEZ/NFPtQeFLsIDOLrGP3bXYr7lFLMhCVsbduF1MXIe8OODkwMFyo1i9ku9NWBwVnVn0jDmIFXjDRg==
dependencies:
compare-func "^1.3.1"
q "^1.5.1"
conventional-changelog-core@^3.2.2:
version "3.2.2"
resolved "https://registry.verdaccio.org/conventional-changelog-core/-/conventional-changelog-core-3.2.2.tgz#de41e6b4a71011a18bcee58e744f6f8f0e7c29c0"
integrity sha512-cssjAKajxaOX5LNAJLB+UOcoWjAIBvXtDMedv/58G+YEmAXMNfC16mmPl0JDOuVJVfIqM0nqQiZ8UCm8IXbE0g==
dependencies:
conventional-changelog-writer "^4.0.5"
conventional-commits-parser "^3.0.2"
conventional-changelog-writer "^3.0.9"
conventional-commits-parser "^2.1.7"
dateformat "^3.0.0"
get-pkg-repo "^1.0.0"
git-raw-commits "2.0.0"
git-raw-commits "^1.3.6"
git-remote-origin-url "^2.0.0"
git-semver-tags "^2.0.2"
git-semver-tags "^1.3.6"
lodash "^4.2.1"
normalize-package-data "^2.3.5"
q "^1.5.1"
read-pkg "^3.0.0"
read-pkg-up "^3.0.0"
through2 "^3.0.0"
read-pkg "^1.1.0"
read-pkg-up "^1.0.1"
through2 "^2.0.0"
conventional-changelog-ember@^2.0.2:
version "2.0.2"
resolved "https://registry.verdaccio.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.2.tgz#284ffdea8c83ea8c210b65c5b4eb3e5cc0f4f51a"
integrity sha512-qtZbA3XefO/n6DDmkYywDYi6wDKNNc98MMl2F9PKSaheJ25Trpi3336W8fDlBhq0X+EJRuseceAdKLEMmuX2tg==
conventional-changelog-ember@^0.3.12:
version "0.3.12"
resolved "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-0.3.12.tgz#b7d31851756d0fcb49b031dffeb6afa93b202400"
integrity sha512-mmJzA7uzbrOqeF89dMMi6z17O07ORTXlTMArnLG9ZTX4oLaKNolUlxFUFlFm9JUoVWajVpaHQWjxH1EOQ+ARoQ==
dependencies:
q "^1.5.1"
conventional-changelog-eslint@^3.0.2:
version "3.0.2"
resolved "https://registry.verdaccio.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.2.tgz#e9eb088cda6be3e58b2de6a5aac63df0277f3cbe"
integrity sha512-Yi7tOnxjZLXlCYBHArbIAm8vZ68QUSygFS7PgumPRiEk+9NPUeucy5Wg9AAyKoBprSV3o6P7Oghh4IZSLtKCvQ==
conventional-changelog-eslint@^1.0.9:
version "1.0.9"
resolved "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-1.0.9.tgz#b13cc7e4b472c819450ede031ff1a75c0e3d07d3"
integrity sha512-h87nfVh2fdk9fJIvz26wCBsbDC/KxqCc5wSlNMZbXcARtbgNbNDIF7Y7ctokFdnxkzVdaHsbINkh548T9eBA7Q==
dependencies:
q "^1.5.1"
conventional-changelog-express@^2.0.1:
version "2.0.1"
resolved "https://registry.verdaccio.org/conventional-changelog-express/-/conventional-changelog-express-2.0.1.tgz#fea2231d99a5381b4e6badb0c1c40a41fcacb755"
integrity sha512-G6uCuCaQhLxdb4eEfAIHpcfcJ2+ao3hJkbLrw/jSK/eROeNfnxCJasaWdDAfFkxsbpzvQT4W01iSynU3OoPLIw==
conventional-changelog-express@^0.3.6:
version "0.3.6"
resolved "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-0.3.6.tgz#4a6295cb11785059fb09202180d0e59c358b9c2c"
integrity sha512-3iWVtBJZ9RnRnZveNDzOD8QRn6g6vUif0qVTWWyi5nUIAbuN1FfPVyKdAlJJfp5Im+dE8Kiy/d2SpaX/0X678Q==
dependencies:
q "^1.5.1"
conventional-changelog-jquery@^3.0.4:
version "3.0.4"
resolved "https://registry.verdaccio.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.4.tgz#7eb598467b83db96742178e1e8d68598bffcd7ae"
integrity sha512-IVJGI3MseYoY6eybknnTf9WzeQIKZv7aNTm2KQsiFVJH21bfP2q7XVjfoMibdCg95GmgeFlaygMdeoDDa+ZbEQ==
conventional-changelog-jquery@^0.1.0:
version "0.1.0"
resolved "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-0.1.0.tgz#0208397162e3846986e71273b6c79c5b5f80f510"
integrity sha1-Agg5cWLjhGmG5xJztsecW1+A9RA=
dependencies:
q "^1.5.1"
q "^1.4.1"
conventional-changelog-jshint@^2.0.1:
version "2.0.1"
resolved "https://registry.verdaccio.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.1.tgz#11c0e8283abf156a4ff78e89be6fdedf9bd72202"
integrity sha512-kRFJsCOZzPFm2tzRHULWP4tauGMvccOlXYf3zGeuSW4U0mZhk5NsjnRZ7xFWrTFPlCLV+PNmHMuXp5atdoZmEg==
conventional-changelog-jscs@^0.1.0:
version "0.1.0"
resolved "https://registry.npmjs.org/conventional-changelog-jscs/-/conventional-changelog-jscs-0.1.0.tgz#0479eb443cc7d72c58bf0bcf0ef1d444a92f0e5c"
integrity sha1-BHnrRDzH1yxYvwvPDvHURKkvDlw=
dependencies:
q "^1.4.1"
conventional-changelog-jshint@^0.3.8:
version "0.3.8"
resolved "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-0.3.8.tgz#9051c1ac0767abaf62a31f74d2fe8790e8acc6c8"
integrity sha512-hn9QU4ZI/5V50wKPJNPGT4gEWgiBFpV6adieILW4MaUFynuDYOvQ71EMSj3EznJyKi/KzuXpc9dGmX8njZMjig==
dependencies:
compare-func "^1.3.1"
q "^1.5.1"
conventional-changelog-preset-loader@^1.1.8:
version "1.1.8"
resolved "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-1.1.8.tgz#40bb0f142cd27d16839ec6c74ee8db418099b373"
integrity sha512-MkksM4G4YdrMlT2MbTsV2F6LXu/hZR0Tc/yenRrDIKRwBl/SP7ER4ZDlglqJsCzLJi4UonBc52Bkm5hzrOVCcw==
conventional-changelog-preset-loader@^2.1.1:
version "2.1.1"
resolved "https://registry.verdaccio.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.1.1.tgz#65bb600547c56d5627d23135154bcd9a907668c4"
integrity sha512-K4avzGMLm5Xw0Ek/6eE3vdOXkqnpf9ydb68XYmCc16cJ99XMMbc2oaNMuPwAsxVK6CC1yA4/I90EhmWNj0Q6HA==
conventional-changelog-writer@^4.0.5:
version "4.0.5"
resolved "https://registry.verdaccio.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.5.tgz#fb9e384bb294e8e8a9f2568a3f4d1e11953d8641"
integrity sha512-g/Myp4MaJ1A+f7Ai+SnVhkcWtaHk6flw0SYN7A+vQ+MTu0+gSovQWs4Pg4NtcNUcIztYQ9YHsoxHP+GGQplI7Q==
conventional-changelog-writer@^3.0.9:
version "3.0.9"
resolved "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-3.0.9.tgz#4aecdfef33ff2a53bb0cf3b8071ce21f0e994634"
integrity sha512-n9KbsxlJxRQsUnK6wIBRnARacvNnN4C/nxnxCkH+B/R1JS2Fa+DiP1dU4I59mEDEjgnFaN2+9wr1P1s7GYB5/Q==
dependencies:
compare-func "^1.3.1"
conventional-commits-filter "^2.0.2"
conventional-commits-filter "^1.1.6"
dateformat "^3.0.0"
handlebars "^4.1.0"
handlebars "^4.0.2"
json-stringify-safe "^5.0.1"
lodash "^4.2.1"
meow "^4.0.0"
semver "^5.5.0"
split "^1.0.0"
through2 "^3.0.0"
through2 "^2.0.0"
conventional-changelog@^3.0.6:
version "3.1.3"
resolved "https://registry.verdaccio.org/conventional-changelog/-/conventional-changelog-3.1.3.tgz#decb10d89c46c838e74eb5160bcf4987992f7534"
integrity sha512-JBfdDSdSGasTNaBRZbOeFn8CJTIpP/sB/kiawmWAiLapLZ+wCDVDZR6Q+Hh9rjh3dxNAFR03bWTeqjKajXvPYA==
conventional-changelog@^1.0.0, conventional-changelog@^3.0.6:
version "1.1.24"
resolved "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-1.1.24.tgz#3d94c29c960f5261c002678315b756cdd3d7d1f0"
integrity sha512-2WcSUst4Y3Z4hHvoMTWXMJr/DmgVdLiMOVY1Kak2LfFz+GIz2KDp5naqbFesYbfXPmaZ5p491dO0FWZIJoJw1Q==
dependencies:
conventional-changelog-angular "^5.0.3"
conventional-changelog-atom "^2.0.1"
conventional-changelog-codemirror "^2.0.1"
conventional-changelog-conventionalcommits "^1.1.1"
conventional-changelog-core "^3.2.2"
conventional-changelog-ember "^2.0.2"
conventional-changelog-eslint "^3.0.2"
conventional-changelog-express "^2.0.1"
conventional-changelog-jquery "^3.0.4"
conventional-changelog-jshint "^2.0.1"
conventional-changelog-preset-loader "^2.1.1"
conventional-changelog-angular "^1.6.6"
conventional-changelog-atom "^0.2.8"
conventional-changelog-codemirror "^0.3.8"
conventional-changelog-core "^2.0.11"
conventional-changelog-ember "^0.3.12"
conventional-changelog-eslint "^1.0.9"
conventional-changelog-express "^0.3.6"
conventional-changelog-jquery "^0.1.0"
conventional-changelog-jscs "^0.1.0"
conventional-changelog-jshint "^0.3.8"
conventional-changelog-preset-loader "^1.1.8"
conventional-commits-filter@^1.1.6:
version "1.1.6"
resolved "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-1.1.6.tgz#4389cd8e58fe89750c0b5fb58f1d7f0cc8ad3831"
integrity sha512-KcDgtCRKJCQhyk6VLT7zR+ZOyCnerfemE/CsR3iQpzRRFbLEs0Y6rwk3mpDvtOh04X223z+1xyJ582Stfct/0Q==
dependencies:
is-subset "^0.1.1"
modify-values "^1.0.0"
conventional-commits-filter@^2.0.2:
version "2.0.2"
@ -2779,9 +2783,9 @@ conventional-commits-filter@^2.0.2:
lodash.ismatch "^4.4.0"
modify-values "^1.0.0"
conventional-commits-parser@^2.1.0:
conventional-commits-parser@^2.1.0, conventional-commits-parser@^2.1.7:
version "2.1.7"
resolved "https://registry.verdaccio.org/conventional-commits-parser/-/conventional-commits-parser-2.1.7.tgz#eca45ed6140d72ba9722ee4132674d639e644e8e"
resolved "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-2.1.7.tgz#eca45ed6140d72ba9722ee4132674d639e644e8e"
integrity sha512-BoMaddIEJ6B4QVMSDu9IkVImlGOSGA1I2BQyOZHeLQ6qVOJLcLKn97+fL6dGbzWEiqDzfH4OkcveULmeq2MHFQ==
dependencies:
JSONStream "^1.0.4"
@ -3250,6 +3254,11 @@ end-of-stream@^1.1.0:
dependencies:
once "^1.4.0"
envinfo@7.3.1:
version "7.3.1"
resolved "https://registry.npmjs.org/envinfo/-/envinfo-7.3.1.tgz#892e42f7bf858b3446d9414ad240dbaf8da52f09"
integrity sha512-GvXiDTqLYrORVSCuJCsWHPXF5BFvoWMQA9xX4YVjPT1jyS3aZEHUBwjzxU/6LTPF9ReHgVEbX7IEN5UvSXHw/A==
errno@^0.1.3:
version "0.1.7"
resolved "https://registry.verdaccio.org/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
@ -4081,9 +4090,9 @@ git-raw-commits@2.0.0:
split2 "^2.0.0"
through2 "^2.0.0"
git-raw-commits@^1.3.0:
git-raw-commits@^1.3.0, git-raw-commits@^1.3.6:
version "1.3.6"
resolved "https://registry.verdaccio.org/git-raw-commits/-/git-raw-commits-1.3.6.tgz#27c35a32a67777c1ecd412a239a6c19d71b95aff"
resolved "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-1.3.6.tgz#27c35a32a67777c1ecd412a239a6c19d71b95aff"
integrity sha512-svsK26tQ8vEKnMshTDatSIQSMDdz8CxIIqKsvPqbtV23Etmw6VNaFAitu8zwZ0VrOne7FztwPyRLxK7/DIUTQg==
dependencies:
dargs "^4.0.1"
@ -4100,6 +4109,14 @@ git-remote-origin-url@^2.0.0:
gitconfiglocal "^1.0.0"
pify "^2.3.0"
git-semver-tags@^1.3.6:
version "1.3.6"
resolved "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-1.3.6.tgz#357ea01f7280794fe0927f2806bee6414d2caba5"
integrity sha512-2jHlJnln4D/ECk9FxGEBh3k44wgYdWjWDtMmJPaecjoRmxKo3Y1Lh8GMYuOPu04CHw86NTAODchYjC5pnpMQig==
dependencies:
meow "^4.0.0"
semver "^5.5.0"
git-semver-tags@^2.0.2:
version "2.0.2"
resolved "https://registry.verdaccio.org/git-semver-tags/-/git-semver-tags-2.0.2.tgz#f506ec07caade191ac0c8d5a21bdb8131b4934e3"
@ -4199,9 +4216,9 @@ growly@^1.3.0:
resolved "https://registry.verdaccio.org/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=
handlebars@4.1.2, handlebars@^4.1.0:
handlebars@4.1.2, handlebars@^4.0.2, handlebars@^4.1.0:
version "4.1.2"
resolved "https://registry.verdaccio.org/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67"
resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67"
integrity sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==
dependencies:
neo-async "^2.6.0"
@ -4761,6 +4778,11 @@ is-stream@^1.1.0:
resolved "https://registry.verdaccio.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
is-subset@^0.1.1:
version "0.1.1"
resolved "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6"
integrity sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=
is-symbol@^1.0.2:
version "1.0.2"
resolved "https://registry.verdaccio.org/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38"
@ -6961,7 +6983,7 @@ puppeteer@1.8.0:
rimraf "^2.6.1"
ws "^5.1.1"
q@^1.5.1:
q@^1.4.1, q@^1.5.1:
version "1.5.1"
resolved "https://registry.verdaccio.org/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
@ -7062,7 +7084,7 @@ read-pkg-up@^4.0.0:
find-up "^3.0.0"
read-pkg "^3.0.0"
read-pkg@^1.0.0:
read-pkg@^1.0.0, read-pkg@^1.1.0:
version "1.1.0"
resolved "https://registry.verdaccio.org/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28"
integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=