mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-16 21:56:25 -05:00
feat: partially implement user endpoints with fastify (part1) (#2301)
Partially implemented (wip) - requires follow up for proper token validation - no test included (still experimental) - types refactoring required, still need alignment with other modules
This commit is contained in:
parent
3dc5b5045f
commit
30875acc70
20 changed files with 370 additions and 42 deletions
|
@ -134,6 +134,18 @@ More details in the debug section
|
|||
We use [`debug`](https://www.npmjs.com/package/debug) to add helpful debugging
|
||||
output to the code. Each package has it owns namespace.
|
||||
|
||||
#### Useful Scripts
|
||||
|
||||
To run the application from the source code, ensure the project has been built with `pnpm build`, once this is done, there are few commands that helps to run server:
|
||||
|
||||
- `pnpm start`: Run the server and the UI with `concurrently`, the
|
||||
server runs in the port `8000` and the UI on the port `4873`. This command
|
||||
is useful if you want to contribute mostly on the UI.
|
||||
- `pnpm debug`: Run the server in debug mode `--inspect`, the UI is included but does not have hot reload. For automatic break use `pnpm debug:break`.
|
||||
- `pnpm debug:fastify`: To contribute on the [fastify migration](https://github.com/verdaccio/verdaccio/discussions/2155) this is a temporary command for such purpose.
|
||||
- `pnpm website`: Build the website, for more commands to run the _website_, run `cd website` and then `pnpm serve`, website will run on port `3000`.
|
||||
- `pnpm docker`: Build the docker image. Requires `docker` command available in your system.
|
||||
|
||||
#### Debugging compiled code
|
||||
|
||||
Currently you can only run pre-compiled packages in debug mode. To enable debug
|
||||
|
|
|
@ -127,6 +127,7 @@
|
|||
"_debug:reload": "nodemon -d 3 packages/verdaccio/debug/bootstrap.js",
|
||||
"start:ts": "ts-node packages/verdaccio/src/start.ts -- --listen 8000",
|
||||
"debug": "node --trace-warnings --trace-uncaught --inspect packages/verdaccio/debug/bootstrap.js",
|
||||
"debug:fastify": "node --trace-warnings --trace-uncaught --inspect packages/verdaccio/debug/bootstrap.js -- fastify-server",
|
||||
"debug:break": "node --trace-warnings --trace-uncaught --inspect-brk packages/verdaccio/debug/bootstrap.js",
|
||||
"changeset": "changeset",
|
||||
"changeset:check": "changeset status --since-master",
|
||||
|
|
|
@ -52,6 +52,7 @@ const debug = buildDebug('verdaccio:auth');
|
|||
export interface IBasicAuth<T> {
|
||||
config: T & Config;
|
||||
authenticate(user: string, password: string, cb: Callback): void;
|
||||
invalidateToken?(token: string): Promise<void>;
|
||||
changePassword(user: string, password: string, newPassword: string, cb: Callback): void;
|
||||
allow_access(pkg: AuthPluginPackage, user: RemoteUser, callback: Callback): void;
|
||||
add_user(user: string, password: string, cb: Callback): any;
|
||||
|
@ -83,6 +84,7 @@ export interface IAuth extends IBasicAuth<Config>, IAuthMiddleware, TokenEncrypt
|
|||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
plugins: any[];
|
||||
allow_unpublish(pkg: AuthPluginPackage, user: RemoteUser, callback: Callback): void;
|
||||
invalidateToken(token: string): Promise<void>;
|
||||
}
|
||||
|
||||
class Auth implements IAuth {
|
||||
|
@ -177,6 +179,12 @@ class Auth implements IAuth {
|
|||
}
|
||||
}
|
||||
|
||||
public async invalidateToken(token: string) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('invalidate token pending to implement', token);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public authenticate(username: string, password: string, cb: Callback): void {
|
||||
const plugins = this.plugins.slice(0);
|
||||
(function next(): void {
|
||||
|
@ -413,7 +421,9 @@ class Auth implements IAuth {
|
|||
}
|
||||
|
||||
// in case auth header does not exist we return anonymous function
|
||||
req.remote_user = createAnonymousRemoteUser();
|
||||
const remoteUser = createAnonymousRemoteUser();
|
||||
req.remote_user = remoteUser;
|
||||
res.locals.remote_user = remoteUser;
|
||||
|
||||
const { authorization } = req.headers;
|
||||
if (_.isNil(authorization)) {
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Cli } from 'clipanion';
|
|||
import { InfoCommand } from './commands/info';
|
||||
import { InitCommand } from './commands/init';
|
||||
import { VersionCommand } from './commands/version';
|
||||
import { NewServer } from './commands/newServer';
|
||||
import { FastifyServer } from './commands/FastifyServer';
|
||||
import { isVersionValid, MIN_NODE_VERSION } from './utils';
|
||||
|
||||
if (process.getuid && process.getuid() === 0) {
|
||||
|
@ -28,7 +28,7 @@ const cli = new Cli({
|
|||
cli.register(InfoCommand);
|
||||
cli.register(InitCommand);
|
||||
cli.register(VersionCommand);
|
||||
cli.register(NewServer);
|
||||
cli.register(FastifyServer);
|
||||
cli.runExit(args, Cli.defaultContext);
|
||||
|
||||
process.on('uncaughtException', function (err) {
|
||||
|
|
|
@ -9,9 +9,12 @@ export const DEFAULT_PROCESS_NAME: string = 'verdaccio';
|
|||
/**
|
||||
* This command is intended to run the server with Fastify
|
||||
* as a migration step.
|
||||
* More info: https://github.com/verdaccio/verdaccio/discussions/2155
|
||||
* To try out.
|
||||
* pnpm debug:fastify
|
||||
*/
|
||||
export class NewServer extends Command {
|
||||
public static paths = [['new']];
|
||||
export class FastifyServer extends Command {
|
||||
public static paths = [['fastify-server']];
|
||||
|
||||
private port = Option.String('-l,-p,--listen,--port', {
|
||||
description: 'host:port number to listen on (default: localhost:4873)',
|
||||
|
@ -41,9 +44,11 @@ export class NewServer extends Command {
|
|||
this.initLogger(configParsed);
|
||||
|
||||
process.title = web?.title || DEFAULT_PROCESS_NAME;
|
||||
// FIXME: need a way to get version of the package.
|
||||
// const { version, name } = require('../../package.json');
|
||||
const ser = await server({ logger, config: configParsed });
|
||||
await ser.listen(4873);
|
||||
// FIXME: harcoded, this would need to come from the configuration and the --listen flag.
|
||||
await ser.listen(process.env.PORT || 4873);
|
||||
} catch (err: any) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
|
@ -34,15 +34,19 @@
|
|||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/core": "workspace:6.0.0-6-next.2",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.9",
|
||||
"@verdaccio/auth": "workspace:6.0.0-6-next.13",
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/store": "workspace:6.0.0-6-next.14",
|
||||
"@verdaccio/tarball": "workspace:11.0.0-6-next.8",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.7",
|
||||
"abortcontroller-polyfill": "1.7.3",
|
||||
"core-js": "3.17.2",
|
||||
"debug": "4.3.2",
|
||||
"fastify": "3.22.1",
|
||||
"fastify-plugin": "3.0.0",
|
||||
"lodash": "4.17.21",
|
||||
"semver": "7.3.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/* eslint-disable no-console */
|
||||
/* eslint-disable no-invalid-this */
|
||||
import { logger } from '@verdaccio/logger';
|
||||
import { FastifyInstance } from 'fastify';
|
||||
|
||||
async function pingRoute(fastify) {
|
||||
async function pingRoute(fastify: FastifyInstance) {
|
||||
fastify.get('/-/ping', async () => {
|
||||
logger.http('ping endpoint');
|
||||
// @ts-ignore
|
||||
console.log('-storage->', fastify.storage);
|
||||
console.log('-config->', fastify.config);
|
||||
console.log('-config->', fastify.configInstance);
|
||||
return {};
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/* eslint-disable no-console */
|
||||
/* eslint-disable no-invalid-this */
|
||||
import { logger } from '@verdaccio/logger';
|
||||
import { FastifyInstance } from 'fastify';
|
||||
|
||||
async function searchRoute(fastify) {
|
||||
async function searchRoute(fastify: FastifyInstance) {
|
||||
fastify.get('/-/v1/search', async (request, reply) => {
|
||||
// TODO: apply security layer here like in
|
||||
// packages/api/src/v1/search.ts
|
||||
|
@ -10,11 +11,11 @@ async function searchRoute(fastify) {
|
|||
// TODO: review which query fields are mandatory
|
||||
|
||||
const abort = new AbortController();
|
||||
|
||||
request.on('aborted', () => {
|
||||
request.socket.on('aborted', () => {
|
||||
abort.abort();
|
||||
});
|
||||
const { url, query } = request;
|
||||
// @ts-ignore
|
||||
const { url, query } = request.query;
|
||||
const storage = fastify.storage;
|
||||
|
||||
const data = await storage.searchManager?.search({
|
||||
|
|
130
packages/core/server/src/endpoints/user.ts
Normal file
130
packages/core/server/src/endpoints/user.ts
Normal file
|
@ -0,0 +1,130 @@
|
|||
/* eslint-disable no-console */
|
||||
/* eslint-disable no-invalid-this */
|
||||
import _ from 'lodash';
|
||||
import { getAuthenticatedMessage, validatePassword } from '@verdaccio/utils';
|
||||
import { RemoteUser } from '@verdaccio/types';
|
||||
import { logger } from '@verdaccio/logger';
|
||||
import { createRemoteUser } from '@verdaccio/config';
|
||||
import { getApiToken } from '@verdaccio/auth';
|
||||
import buildDebug from 'debug';
|
||||
import { FastifyInstance, FastifyRequest } from 'fastify';
|
||||
|
||||
const debug = buildDebug('verdaccio:api:user');
|
||||
|
||||
async function userRoute(fastify: FastifyInstance) {
|
||||
fastify.get('/:org_couchdb_user', async (request, reply) => {
|
||||
// @ts-expect-error
|
||||
const message = getAuthenticatedMessage(request.userRemote.name);
|
||||
logger.info('user authenticated message %o', message);
|
||||
reply.code(fastify.httpStatuscode.OK);
|
||||
return { ok: message };
|
||||
});
|
||||
|
||||
fastify.delete('/token/:token', async (request: FastifyRequest, reply) => {
|
||||
debug('loging out');
|
||||
// FIXME: type params correctly
|
||||
// @ts-ignore
|
||||
const { token } = request.params;
|
||||
const userRemote: RemoteUser = request.userRemote;
|
||||
await fastify.auth.invalidateToken(token);
|
||||
console.log('userRoute', userRemote);
|
||||
reply.code(fastify.httpStatuscode.OK);
|
||||
return { ok: fastify.apiMessage.LOGGED_OUT };
|
||||
});
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
fastify.put<{
|
||||
Body: { name: string; password: string };
|
||||
}>('/:username', async (request, reply) => {
|
||||
const { name, password } = request.body;
|
||||
const remoteName = request.userRemote.name;
|
||||
if (_.isNil(remoteName) === false && _.isNil(name) === false && remoteName === name) {
|
||||
// debug('login: no remote user detected');
|
||||
fastify.auth.authenticate(
|
||||
name,
|
||||
password,
|
||||
async function callbackAuthenticate(err, user): Promise<void> {
|
||||
if (err) {
|
||||
logger.trace(
|
||||
{ name, err },
|
||||
'authenticating for user @{username} failed. Error: @{err.message}'
|
||||
);
|
||||
reply
|
||||
.code(fastify.httpStatuscode.UNAUTHORIZED)
|
||||
.send(
|
||||
fastify.errorUtils.getCode(
|
||||
fastify.httpStatuscode.UNAUTHORIZED,
|
||||
fastify.apiError.BAD_USERNAME_PASSWORD
|
||||
)
|
||||
);
|
||||
}
|
||||
const restoredRemoteUser: RemoteUser = createRemoteUser(name, user.groups || []);
|
||||
const token = await getApiToken(
|
||||
fastify.auth,
|
||||
fastify.configInstance,
|
||||
restoredRemoteUser,
|
||||
password
|
||||
);
|
||||
debug('login: new token');
|
||||
if (!token) {
|
||||
return reply.send(fastify.errorUtils.getUnauthorized());
|
||||
} else {
|
||||
reply.code(fastify.httpStatuscode.CREATED);
|
||||
const message = getAuthenticatedMessage(remoteName);
|
||||
debug('login: created user message %o', message);
|
||||
reply.send({
|
||||
ok: message,
|
||||
token,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
if (validatePassword(password) === false) {
|
||||
debug('adduser: invalid password');
|
||||
reply.code(fastify.httpStatuscode.BAD_REQUEST).send(
|
||||
fastify.errorUtils.getCode(
|
||||
fastify.httpStatuscode.BAD_REQUEST,
|
||||
// eslint-disable-next-line new-cap
|
||||
fastify.apiError.PASSWORD_SHORT()
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
fastify.auth.add_user(name, password, async function (err, user): Promise<void> {
|
||||
if (err) {
|
||||
if (
|
||||
err.status >= fastify.httpStatuscode.BAD_REQUEST &&
|
||||
err.status < fastify.httpStatuscode.INTERNAL_ERROR
|
||||
) {
|
||||
debug('adduser: error on create user');
|
||||
// With npm registering is the same as logging in,
|
||||
// and npm accepts only an 409 error.
|
||||
// So, changing status code here.
|
||||
const addUserError =
|
||||
fastify.errorUtils.getCode(err.status, err.message) ||
|
||||
fastify.errorUtils.getConflict(err.message);
|
||||
|
||||
reply.send(addUserError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
const token =
|
||||
name && password
|
||||
? await getApiToken(fastify.auth, fastify.configInstance, user, password)
|
||||
: undefined;
|
||||
debug('adduser: new token %o', token);
|
||||
if (!token) {
|
||||
return reply.send(fastify.errorUtils.getUnauthorized());
|
||||
}
|
||||
debug('adduser: user has been created');
|
||||
reply.code(fastify.httpStatuscode.CREATED).send({
|
||||
ok: `user '${name}' created`,
|
||||
token,
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export default userRoute;
|
|
@ -1,5 +1,6 @@
|
|||
import semver from 'semver';
|
||||
|
||||
// FUTURE: remove when v15 is the minimum requirement
|
||||
if (semver.lte(process.version, 'v15.0.0')) {
|
||||
global.AbortController = require('abortcontroller-polyfill/dist/cjs-ponyfill').AbortController;
|
||||
}
|
||||
|
|
21
packages/core/server/src/plugins/auth.ts
Normal file
21
packages/core/server/src/plugins/auth.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import fp from 'fastify-plugin';
|
||||
import { Config as IConfig } from '@verdaccio/types';
|
||||
import { Auth, IAuth } from '@verdaccio/auth';
|
||||
import { FastifyInstance } from 'fastify';
|
||||
|
||||
export default fp(
|
||||
async function (fastify: FastifyInstance, opts: { config: IConfig; filters?: unknown }) {
|
||||
const { config } = opts;
|
||||
const auth: IAuth = new Auth(config);
|
||||
fastify.decorate('auth', auth);
|
||||
},
|
||||
{
|
||||
fastify: '>=3.x',
|
||||
}
|
||||
);
|
||||
|
||||
declare module 'fastify' {
|
||||
interface FastifyInstance {
|
||||
auth: IAuth;
|
||||
}
|
||||
}
|
22
packages/core/server/src/plugins/config.ts
Normal file
22
packages/core/server/src/plugins/config.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
import fp from 'fastify-plugin';
|
||||
|
||||
import { Config as IConfig, ConfigRuntime } from '@verdaccio/types';
|
||||
import { Config as AppConfig } from '@verdaccio/config';
|
||||
import { FastifyInstance } from 'fastify';
|
||||
|
||||
export default fp(
|
||||
async function (fastify: FastifyInstance, opts: { config: ConfigRuntime }) {
|
||||
const { config } = opts;
|
||||
const configInstance: IConfig = new AppConfig(Object.assign({}, config));
|
||||
fastify.decorate('configInstance', configInstance);
|
||||
},
|
||||
{
|
||||
fastify: '>=3.x',
|
||||
}
|
||||
);
|
||||
|
||||
declare module 'fastify' {
|
||||
interface FastifyInstance {
|
||||
configInstance: IConfig;
|
||||
}
|
||||
}
|
25
packages/core/server/src/plugins/coreUtils.ts
Normal file
25
packages/core/server/src/plugins/coreUtils.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import fp from 'fastify-plugin';
|
||||
|
||||
import { errorUtils, validatioUtils, API_ERROR, API_MESSAGE, HTTP_STATUS } from '@verdaccio/core';
|
||||
|
||||
export default fp(
|
||||
async function (fastify) {
|
||||
fastify.decorate('errorUtils', errorUtils);
|
||||
fastify.decorate('apiError', API_ERROR);
|
||||
fastify.decorate('apiMessage', API_MESSAGE);
|
||||
fastify.decorate('validatioUtils', validatioUtils);
|
||||
fastify.decorate('statusCode', HTTP_STATUS);
|
||||
},
|
||||
{
|
||||
fastify: '>=3.x',
|
||||
}
|
||||
);
|
||||
|
||||
declare module 'fastify' {
|
||||
interface FastifyInstance {
|
||||
apiError: typeof API_ERROR;
|
||||
apiMessage: typeof API_MESSAGE;
|
||||
httpStatuscode: typeof HTTP_STATUS;
|
||||
errorUtils: typeof errorUtils;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,23 @@
|
|||
import fp from 'fastify-plugin';
|
||||
import { Config as IConfig } from '@verdaccio/types';
|
||||
import { Storage } from '@verdaccio/store';
|
||||
import { FastifyInstance } from 'fastify';
|
||||
|
||||
export async function storageService(fastify, opts, done) {
|
||||
const { config, filters } = opts;
|
||||
// @ts-ignore
|
||||
const storage: Storage = new Storage(config);
|
||||
await storage.init(config, filters ?? {});
|
||||
fastify.decorate('storage', storage);
|
||||
done();
|
||||
export default fp(
|
||||
async function (fastify: FastifyInstance, opts: { config: IConfig; filters?: unknown }) {
|
||||
const { config } = opts;
|
||||
const storage: Storage = new Storage(config);
|
||||
// @ts-ignore
|
||||
await storage.init(config, {});
|
||||
fastify.decorate('storage', storage);
|
||||
},
|
||||
{
|
||||
fastify: '>=3.x',
|
||||
}
|
||||
);
|
||||
|
||||
declare module 'fastify' {
|
||||
interface FastifyInstance {
|
||||
storage: Storage;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,39 +1,51 @@
|
|||
import { Config as IConfig } from '@verdaccio/types';
|
||||
import { Config as AppConfig } from '@verdaccio/config';
|
||||
import { Config as IConfig, RemoteUser } from '@verdaccio/types';
|
||||
import { Config as AppConfig, createAnonymousRemoteUser } from '@verdaccio/config';
|
||||
|
||||
import fastify from 'fastify';
|
||||
import buildDebug from 'debug';
|
||||
import fp from 'fastify-plugin';
|
||||
|
||||
import ping from './endpoints/ping';
|
||||
import search from './endpoints/search';
|
||||
import { storageService } from './plugins/storage';
|
||||
import storagePlugin from './plugins/storage';
|
||||
import authPlugin from './plugins/auth';
|
||||
import coreUtils from './plugins/coreUtils';
|
||||
import configPlugin from './plugins/config';
|
||||
import ping from './endpoints/ping';
|
||||
import user from './endpoints/user';
|
||||
|
||||
const debug = buildDebug('verdaccio:fastify');
|
||||
|
||||
async function startServer({ logger, config }) {
|
||||
// eslint-disable-next-line prettier/prettier
|
||||
const configInstance: IConfig = new AppConfig(Object.assign({}, config));
|
||||
debug('start server');
|
||||
const app = fastify({ logger });
|
||||
|
||||
app.decorate('config', configInstance);
|
||||
app.register(fp(storageService), { config: configInstance });
|
||||
const fastifyInstance = fastify({ logger });
|
||||
fastifyInstance.decorateRequest<RemoteUser>('userRemote', createAnonymousRemoteUser());
|
||||
fastifyInstance.register(configPlugin, { config });
|
||||
fastifyInstance.register(coreUtils);
|
||||
fastifyInstance.register(authPlugin, { config: configInstance });
|
||||
fastifyInstance.register(storagePlugin, { config: configInstance });
|
||||
|
||||
// api
|
||||
app.register((instance, opts, done) => {
|
||||
instance.decorate('utility', new Map());
|
||||
fastifyInstance.register((instance, opts, done) => {
|
||||
instance.register(ping);
|
||||
instance.register(user, { prefix: '/-/user' });
|
||||
instance.register(search);
|
||||
done();
|
||||
});
|
||||
|
||||
// web
|
||||
app.register((instance, opts, done) => {
|
||||
fastifyInstance.register((instance, opts, done) => {
|
||||
instance.register(ping, { prefix: '/web' });
|
||||
done();
|
||||
});
|
||||
|
||||
return app;
|
||||
return fastifyInstance;
|
||||
}
|
||||
|
||||
declare module 'fastify' {
|
||||
interface FastifyRequest {
|
||||
userRemote: RemoteUser;
|
||||
}
|
||||
}
|
||||
|
||||
export default startServer;
|
||||
|
|
|
@ -8,16 +8,22 @@
|
|||
"exclude": ["src/**/*.test.ts"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../store"
|
||||
"path": "../../store"
|
||||
},
|
||||
{
|
||||
"path": "../config"
|
||||
"path": "../../config"
|
||||
},
|
||||
{
|
||||
"path": "../auth"
|
||||
"path": "../../auth"
|
||||
},
|
||||
{
|
||||
"path": "../logger"
|
||||
"path": "../../logger"
|
||||
},
|
||||
{
|
||||
"path": "../../utils"
|
||||
},
|
||||
{
|
||||
"path": "../../core/core"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -38,7 +38,8 @@
|
|||
"build": "exit 0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "14.6.0"
|
||||
"@types/node": "14.6.0",
|
||||
"tsd": "0.18.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
|
|
|
@ -7,7 +7,7 @@ import RateLimit from 'express-rate-limit';
|
|||
import { HttpError } from 'http-errors';
|
||||
|
||||
import { loadPlugin } from '@verdaccio/loaders';
|
||||
import { Auth } from '@verdaccio/auth';
|
||||
import { Auth, IBasicAuth } from '@verdaccio/auth';
|
||||
import apiEndpoint from '@verdaccio/api';
|
||||
import { API_ERROR, HTTP_STATUS, errorUtils } from '@verdaccio/core';
|
||||
import { Config as AppConfig } from '@verdaccio/config';
|
||||
|
@ -15,7 +15,6 @@ import { Config as AppConfig } from '@verdaccio/config';
|
|||
import webMiddleware from '@verdaccio/web';
|
||||
import { ConfigRuntime } from '@verdaccio/types';
|
||||
|
||||
import { IAuth, IBasicAuth } from '@verdaccio/auth';
|
||||
import { Storage } from '@verdaccio/store';
|
||||
import { logger } from '@verdaccio/logger';
|
||||
import { log, final, errorReportingMiddleware } from '@verdaccio/middleware';
|
||||
|
@ -33,7 +32,7 @@ export interface IPluginMiddleware<T> extends IPlugin<T> {
|
|||
const debug = buildDebug('verdaccio:server');
|
||||
|
||||
const defineAPI = function (config: IConfig, storage: Storage): any {
|
||||
const auth: IAuth = new Auth(config);
|
||||
const auth: Auth = new Auth(config);
|
||||
const app: Application = express();
|
||||
const limiter = new RateLimit(config.serverSettings.rateLimit);
|
||||
// run in production mode by default, just in case
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export function isNil(value: any): boolean {
|
||||
return value == null;
|
||||
return value === null || typeof value === 'undefined';
|
||||
}
|
||||
|
||||
export function isFunction(value): boolean {
|
||||
|
|
|
@ -348,26 +348,34 @@ importers:
|
|||
'@types/node': 16.9.1
|
||||
'@verdaccio/auth': workspace:6.0.0-6-next.13
|
||||
'@verdaccio/config': workspace:6.0.0-6-next.9
|
||||
'@verdaccio/core': workspace:6.0.0-6-next.2
|
||||
'@verdaccio/logger': workspace:6.0.0-6-next.6
|
||||
'@verdaccio/store': workspace:6.0.0-6-next.14
|
||||
'@verdaccio/tarball': workspace:11.0.0-6-next.8
|
||||
'@verdaccio/types': workspace:11.0.0-6-next.9
|
||||
'@verdaccio/utils': workspace:6.0.0-6-next.7
|
||||
abortcontroller-polyfill: 1.7.3
|
||||
core-js: 3.17.2
|
||||
debug: 4.3.2
|
||||
fastify: 3.22.1
|
||||
fastify-plugin: 3.0.0
|
||||
lodash: 4.17.21
|
||||
semver: 7.3.5
|
||||
ts-node: 10.2.1
|
||||
dependencies:
|
||||
'@verdaccio/auth': link:../../auth
|
||||
'@verdaccio/config': link:../../config
|
||||
'@verdaccio/core': link:../core
|
||||
'@verdaccio/logger': link:../../logger
|
||||
'@verdaccio/store': link:../../store
|
||||
'@verdaccio/tarball': link:../tarball
|
||||
'@verdaccio/utils': link:../../utils
|
||||
abortcontroller-polyfill: 1.7.3
|
||||
core-js: 3.17.2
|
||||
debug: 4.3.2
|
||||
fastify: 3.22.1
|
||||
fastify-plugin: 3.0.0
|
||||
lodash: 4.17.21
|
||||
semver: 7.3.5
|
||||
devDependencies:
|
||||
'@types/node': 16.9.1
|
||||
|
@ -402,8 +410,10 @@ importers:
|
|||
packages/core/types:
|
||||
specifiers:
|
||||
'@types/node': 14.6.0
|
||||
tsd: 0.18.0
|
||||
devDependencies:
|
||||
'@types/node': 14.6.0
|
||||
tsd: 0.18.0
|
||||
|
||||
packages/core/url:
|
||||
specifiers:
|
||||
|
@ -6085,6 +6095,11 @@ packages:
|
|||
resolution: {integrity: sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==}
|
||||
dev: true
|
||||
|
||||
/@tsd/typescript/4.4.4:
|
||||
resolution: {integrity: sha512-XNaotnbhU6sKSXYg9rVz4L9i9g+j+x1IIgMPztK8KumtMEsrLXcqPBKp/qzmUKwAZEqgHs4+TTz90dUu5/aIqQ==}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/@types/activedirectory2/1.2.3:
|
||||
resolution: {integrity: sha512-yZERTOJFrOAax2HbDyBBhAKyUEa1PC/GXMe9UGBGyeOF0ZRRBKnIMNXVAYfveJMyrhUBhdRoObwe3CBPoekyjQ==}
|
||||
dependencies:
|
||||
|
@ -6179,6 +6194,13 @@ packages:
|
|||
'@types/estree': 0.0.50
|
||||
'@types/json-schema': 7.0.8
|
||||
|
||||
/@types/eslint/7.28.2:
|
||||
resolution: {integrity: sha512-KubbADPkfoU75KgKeKLsFHXnU4ipH7wYg0TRT33NK3N3yiu7jlFAAoygIWBV+KbuHx/G+AvuGX6DllnK35gfJA==}
|
||||
dependencies:
|
||||
'@types/estree': 0.0.50
|
||||
'@types/json-schema': 7.0.8
|
||||
dev: true
|
||||
|
||||
/@types/estree/0.0.47:
|
||||
resolution: {integrity: sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==}
|
||||
dev: false
|
||||
|
@ -10886,6 +10908,20 @@ packages:
|
|||
eslint: 7.32.0
|
||||
dev: false
|
||||
|
||||
/eslint-formatter-pretty/4.1.0:
|
||||
resolution: {integrity: sha512-IsUTtGxF1hrH6lMWiSl1WbGaiP01eT6kzywdY1U+zLc0MP+nwEnUiS9UI8IaOTUhTeQJLlCEWIbXINBH4YJbBQ==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
'@types/eslint': 7.28.2
|
||||
ansi-escapes: 4.3.2
|
||||
chalk: 4.1.2
|
||||
eslint-rule-docs: 1.1.231
|
||||
log-symbols: 4.1.0
|
||||
plur: 4.0.0
|
||||
string-width: 4.2.2
|
||||
supports-hyperlinks: 2.2.0
|
||||
dev: true
|
||||
|
||||
/eslint-import-resolver-node/0.3.4:
|
||||
resolution: {integrity: sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==}
|
||||
dependencies:
|
||||
|
@ -11048,6 +11084,10 @@ packages:
|
|||
engines: {node: '>=4.0.0'}
|
||||
dev: false
|
||||
|
||||
/eslint-rule-docs/1.1.231:
|
||||
resolution: {integrity: sha512-egHz9A1WG7b8CS0x1P6P/Rj5FqZOjray/VjpJa14tMZalfRKvpE2ONJ3plCM7+PcinmU4tcmbPLv0VtwzSdLVA==}
|
||||
dev: true
|
||||
|
||||
/eslint-scope/5.1.1:
|
||||
resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
@ -13129,6 +13169,11 @@ packages:
|
|||
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
/irregular-plurals/3.3.0:
|
||||
resolution: {integrity: sha512-MVBLKUTangM3EfRPFROhmWQQKRDsrgI83J8GS3jXy+OwYqiR2/aoWndYQ5416jLE3uaGgLH7ncme3X9y09gZ3g==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/is-absolute-url/3.0.3:
|
||||
resolution: {integrity: sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -16512,6 +16557,13 @@ packages:
|
|||
semver-compare: 1.0.0
|
||||
dev: true
|
||||
|
||||
/plur/4.0.0:
|
||||
resolution: {integrity: sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
irregular-plurals: 3.3.0
|
||||
dev: true
|
||||
|
||||
/pn/1.1.0:
|
||||
resolution: {integrity: sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==}
|
||||
dev: true
|
||||
|
@ -20478,6 +20530,19 @@ packages:
|
|||
strip-bom: 3.0.0
|
||||
dev: false
|
||||
|
||||
/tsd/0.18.0:
|
||||
resolution: {integrity: sha512-UIkxm2CLmSjXlQs4zqxgVV9UmzK8VgJ63eBpgkH/ZsMkiUdzxxHvdCCg8F314HDxzfQl2muJEy/TEcXHIFIPXg==}
|
||||
engines: {node: '>=12'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@tsd/typescript': 4.4.4
|
||||
eslint-formatter-pretty: 4.1.0
|
||||
globby: 11.0.4
|
||||
meow: 9.0.0
|
||||
path-exists: 4.0.0
|
||||
read-pkg-up: 7.0.1
|
||||
dev: true
|
||||
|
||||
/tslib/1.14.1:
|
||||
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
|
||||
|
||||
|
|
Loading…
Reference in a new issue