UNPKG

@verdaccio/web

Version:
92 lines (83 loc) 2.79 kB
import buildDebug from 'debug'; import { Router } from 'express'; import _ from 'lodash'; import { URLSearchParams } from 'url'; import { Auth } from '@verdaccio/auth'; import { errorUtils, searchUtils } from '@verdaccio/core'; import { SearchQuery } from '@verdaccio/core/src/search-utils'; import { Storage } from '@verdaccio/store'; import { Manifest } from '@verdaccio/types'; import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from './package'; const debug = buildDebug('verdaccio:web:api:search'); function checkAccess(pkg: any, auth: any, remoteUser): Promise<Manifest | null> { return new Promise((resolve, reject) => { auth.allow_access({ packageName: pkg?.package?.name }, remoteUser, function (err, allowed) { if (err) { if (err.status && String(err.status).match(/^4\d\d$/)) { // auth plugin returns 4xx user error, // that's equivalent of !allowed basically allowed = false; return resolve(null); } else { reject(err); } } else { return resolve(allowed ? pkg : null); } }); }); } function addSearchWebApi(storage: Storage, auth: Auth): Router { const router = Router(); /* eslint new-cap: 0 */ router.get( '/search/:anything', async function ( req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer ): Promise<void> { try { let data; const abort = new AbortController(); req.socket.on('close', function () { debug('search web aborted'); abort.abort(); }); const text: string = (req.params.anything as string) ?? ''; // These values are declared as optimal by npm cli // FUTURE: could be overwritten by ui settings. const size = 20; const from = 0; const query: SearchQuery = { from: 0, maintenance: 0.5, popularity: 0.98, quality: 0.65, size: 20, text, }; // @ts-ignore const urlParams = new URLSearchParams(query); debug('search web init'); data = await storage?.search({ query, url: `/-/v1/search?${urlParams.toString()}`, abort, }); const checkAccessPromises: searchUtils.SearchItemPkg[] = await Promise.all( data.map((pkgItem) => { return checkAccess(pkgItem, auth, req.remote_user); }) ); const final: searchUtils.SearchItemPkg[] = checkAccessPromises .filter((i) => !_.isNull(i)) .slice(from, size); next(final); } catch (err: any) { next(errorUtils.getInternalError(err.message)); } } ); return router; } export default addSearchWebApi;