@verdaccio/web 9.0.0-next-9.6 → 9.0.0-next-9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/api/package.js +2 -3
- package/build/api/package.js.map +1 -1
- package/build/api/package.mjs +2 -2
- package/build/api/package.mjs.map +1 -1
- package/build/api/search.js +1 -3
- package/build/api/search.js.map +1 -1
- package/build/api/search.mjs +1 -2
- package/build/api/search.mjs.map +1 -1
- package/build/api/user.js +3 -4
- package/build/api/user.js.map +1 -1
- package/build/api/user.mjs +3 -3
- package/build/api/user.mjs.map +1 -1
- package/build/middleware.js +3 -4
- package/build/middleware.js.map +1 -1
- package/build/middleware.mjs +3 -3
- package/build/middleware.mjs.map +1 -1
- package/build/web-utils.js +4 -5
- package/build/web-utils.js.map +1 -1
- package/build/web-utils.mjs +3 -3
- package/build/web-utils.mjs.map +1 -1
- package/package.json +14 -13
package/build/api/package.js
CHANGED
|
@@ -2,8 +2,7 @@ const require_runtime = require("../_virtual/_rolldown/runtime.js");
|
|
|
2
2
|
const require_web_utils = require("../web-utils.js");
|
|
3
3
|
const require_author_utils = require("../author-utils.js");
|
|
4
4
|
let express = require("express");
|
|
5
|
-
let
|
|
6
|
-
lodash = require_runtime.__toESM(lodash);
|
|
5
|
+
let lodash_es = require("lodash-es");
|
|
7
6
|
let _verdaccio_logger = require("@verdaccio/logger");
|
|
8
7
|
let _verdaccio_middleware = require("@verdaccio/middleware");
|
|
9
8
|
let debug = require("debug");
|
|
@@ -46,7 +45,7 @@ function addPackageWebApi(storage, auth, config) {
|
|
|
46
45
|
try {
|
|
47
46
|
if (await checkAllow(pkg.name, req.remote_user)) {
|
|
48
47
|
if (config.web) pkgCopy.author.avatar = require_author_utils.generateGravatarUrl(pkgCopy.author.email, config.web.gravatar);
|
|
49
|
-
if (!
|
|
48
|
+
if (!(0, lodash_es.isNil)(pkgCopy.dist) && pkgCopy.dist.tarball !== null) pkgCopy.dist.tarball = (0, _verdaccio_tarball.getLocalRegistryTarballUri)(pkgCopy.dist.tarball, pkg.name, requestOptions, config?.url_prefix);
|
|
50
49
|
permissions.push(pkgCopy);
|
|
51
50
|
}
|
|
52
51
|
} catch (err) {
|
package/build/api/package.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package.js","names":[],"sources":["../../src/api/package.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Router } from 'express';\nimport
|
|
1
|
+
{"version":3,"file":"package.js","names":[],"sources":["../../src/api/package.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Router } from 'express';\nimport { isNil } from 'lodash-es';\n\nimport type { Auth } from '@verdaccio/auth';\nimport { createAnonymousRemoteUser } from '@verdaccio/config';\nimport { logger } from '@verdaccio/logger';\nimport {\n $NextFunctionVer,\n $RequestExtend,\n $ResponseExtend,\n WebUrls,\n getRequestOptions,\n} from '@verdaccio/middleware';\nimport type { Storage } from '@verdaccio/store';\nimport { getLocalRegistryTarballUri } from '@verdaccio/tarball';\nimport type { Config, RemoteUser, Version } from '@verdaccio/types';\n\nimport { formatAuthor, generateGravatarUrl } from '../author-utils';\nimport { hasLogin, sortByName, sortByTime } from '../web-utils';\n\nexport { $RequestExtend, $ResponseExtend, $NextFunctionVer }; // Was required by other packages\n\nconst getField = (field = 'name') => {\n return field === 'name' || field === 'time' ? field : 'name';\n};\n\nconst getOrder = (order = 'asc') => {\n return order === 'asc';\n};\n\nconst debug = buildDebug('verdaccio:web:api:package');\n\nfunction addPackageWebApi(storage: Storage, auth: Auth, config: Config): Router {\n const isLoginEnabled = hasLogin(config);\n debug('is login enabled: %o', isLoginEnabled);\n const pkgRouter = Router(); /* eslint new-cap: 0 */\n const anonymousRemoteUser: RemoteUser = createAnonymousRemoteUser();\n\n debug('initialized package web api');\n const checkAllow = (name: string, remoteUser: RemoteUser): Promise<boolean> =>\n new Promise((resolve, reject): void => {\n const remoteUserAccess = !isLoginEnabled ? anonymousRemoteUser : remoteUser;\n try {\n auth.allow_access({ packageName: name }, remoteUserAccess, (err, allowed): void => {\n if (err) {\n resolve(false);\n }\n return resolve(allowed as boolean);\n });\n } catch (err: any) {\n reject(err);\n }\n });\n\n async function processPackages(packages: Version[] = [], req): Promise<Version[]> {\n const permissions: Version[] = [];\n const packagesToProcess = packages.slice();\n debug('process packages %o', packagesToProcess);\n const requestOptions = getRequestOptions(req);\n for (const pkg of packagesToProcess) {\n const pkgCopy = { ...pkg };\n pkgCopy.author = formatAuthor(pkg.author);\n try {\n if (await checkAllow(pkg.name, req.remote_user)) {\n if (config.web) {\n // @ts-ignore\n pkgCopy.author.avatar = generateGravatarUrl(pkgCopy.author.email, config.web.gravatar);\n }\n // convert any remote dist to a local reference\n // eg: if the dist points to npmjs, switch to localhost:4873/prefix/etc.tar.gz\n if (!isNil(pkgCopy.dist) && pkgCopy.dist.tarball !== null) {\n pkgCopy.dist.tarball = getLocalRegistryTarballUri(\n pkgCopy.dist.tarball,\n pkg.name,\n requestOptions,\n config?.url_prefix\n );\n }\n permissions.push(pkgCopy);\n }\n } catch (err: any) {\n debug('process packages error %o', err);\n logger.error(\n { name: pkg.name, error: err },\n 'permission process for @{name} has failed: @{error}'\n );\n throw err;\n }\n }\n\n debug('allowed %o packages', permissions.length);\n return permissions;\n }\n\n // Get list of all visible package\n pkgRouter.get(\n WebUrls.packages_all,\n async function (\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n ): Promise<void> {\n debug('hit package web api %o');\n\n try {\n const localPackages: Version[] = await storage.getLocalDatabase();\n\n const field = getField(config?.web?.sort_field);\n const order = getOrder(config?.web?.sort_packages);\n debug('order by %o %o', field, order);\n const pkgs = await processPackages(localPackages, req);\n if (field === 'name') next(sortByName(pkgs, order));\n else next(sortByTime(pkgs, order));\n } catch (error: any) {\n next(error);\n }\n }\n );\n\n return pkgRouter;\n}\n\nexport default addPackageWebApi;\n"],"mappings":";;;;;;;;;;;;AAuBA,IAAM,YAAY,QAAQ,WAAW;AACnC,QAAO,UAAU,UAAU,UAAU,SAAS,QAAQ;;AAGxD,IAAM,YAAY,QAAQ,UAAU;AAClC,QAAO,UAAU;;AAGnB,IAAM,WAAA,GAAA,MAAA,SAAmB,4BAA4B;AAErD,SAAS,iBAAiB,SAAkB,MAAY,QAAwB;CAC9E,MAAM,iBAAiB,kBAAA,SAAS,OAAO;AACvC,SAAM,wBAAwB,eAAe;CAC7C,MAAM,aAAA,GAAA,QAAA,SAAoB;CAC1B,MAAM,uBAAA,GAAA,kBAAA,4BAA6D;AAEnE,SAAM,8BAA8B;CACpC,MAAM,cAAc,MAAc,eAChC,IAAI,SAAS,SAAS,WAAiB;EACrC,MAAM,mBAAmB,CAAC,iBAAiB,sBAAsB;AACjE,MAAI;AACF,QAAK,aAAa,EAAE,aAAa,MAAM,EAAE,mBAAmB,KAAK,YAAkB;AACjF,QAAI,IACF,SAAQ,MAAM;AAEhB,WAAO,QAAQ,QAAmB;KAClC;WACK,KAAU;AACjB,UAAO,IAAI;;GAEb;CAEJ,eAAe,gBAAgB,WAAsB,EAAE,EAAE,KAAyB;EAChF,MAAM,cAAyB,EAAE;EACjC,MAAM,oBAAoB,SAAS,OAAO;AAC1C,UAAM,uBAAuB,kBAAkB;EAC/C,MAAM,kBAAA,GAAA,sBAAA,mBAAmC,IAAI;AAC7C,OAAK,MAAM,OAAO,mBAAmB;GACnC,MAAM,UAAU,EAAE,GAAG,KAAK;AAC1B,WAAQ,SAAS,qBAAA,aAAa,IAAI,OAAO;AACzC,OAAI;AACF,QAAI,MAAM,WAAW,IAAI,MAAM,IAAI,YAAY,EAAE;AAC/C,SAAI,OAAO,IAET,SAAQ,OAAO,SAAS,qBAAA,oBAAoB,QAAQ,OAAO,OAAO,OAAO,IAAI,SAAS;AAIxF,SAAI,EAAA,GAAA,UAAA,OAAO,QAAQ,KAAK,IAAI,QAAQ,KAAK,YAAY,KACnD,SAAQ,KAAK,WAAA,GAAA,mBAAA,4BACX,QAAQ,KAAK,SACb,IAAI,MACJ,gBACA,QAAQ,WACT;AAEH,iBAAY,KAAK,QAAQ;;YAEpB,KAAU;AACjB,YAAM,6BAA6B,IAAI;AACvC,sBAAA,OAAO,MACL;KAAE,MAAM,IAAI;KAAM,OAAO;KAAK,EAC9B,sDACD;AACD,UAAM;;;AAIV,UAAM,uBAAuB,YAAY,OAAO;AAChD,SAAO;;AAIT,WAAU,IACR,sBAAA,QAAQ,cACR,eACE,KACA,KACA,MACe;AACf,UAAM,yBAAyB;AAE/B,MAAI;GACF,MAAM,gBAA2B,MAAM,QAAQ,kBAAkB;GAEjE,MAAM,QAAQ,SAAS,QAAQ,KAAK,WAAW;GAC/C,MAAM,QAAQ,SAAS,QAAQ,KAAK,cAAc;AAClD,WAAM,kBAAkB,OAAO,MAAM;GACrC,MAAM,OAAO,MAAM,gBAAgB,eAAe,IAAI;AACtD,OAAI,UAAU,OAAQ,MAAK,kBAAA,WAAW,MAAM,MAAM,CAAC;OAC9C,MAAK,kBAAA,WAAW,MAAM,MAAM,CAAC;WAC3B,OAAY;AACnB,QAAK,MAAM;;GAGhB;AAED,QAAO"}
|
package/build/api/package.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { hasLogin, sortByName, sortByTime } from "../web-utils.mjs";
|
|
2
2
|
import { formatAuthor, generateGravatarUrl } from "../author-utils.mjs";
|
|
3
3
|
import { Router } from "express";
|
|
4
|
-
import
|
|
4
|
+
import { isNil } from "lodash-es";
|
|
5
5
|
import { logger } from "@verdaccio/logger";
|
|
6
6
|
import { WebUrls, getRequestOptions } from "@verdaccio/middleware";
|
|
7
7
|
import buildDebug from "debug";
|
|
@@ -43,7 +43,7 @@ function addPackageWebApi(storage, auth, config) {
|
|
|
43
43
|
try {
|
|
44
44
|
if (await checkAllow(pkg.name, req.remote_user)) {
|
|
45
45
|
if (config.web) pkgCopy.author.avatar = generateGravatarUrl(pkgCopy.author.email, config.web.gravatar);
|
|
46
|
-
if (!
|
|
46
|
+
if (!isNil(pkgCopy.dist) && pkgCopy.dist.tarball !== null) pkgCopy.dist.tarball = getLocalRegistryTarballUri(pkgCopy.dist.tarball, pkg.name, requestOptions, config?.url_prefix);
|
|
47
47
|
permissions.push(pkgCopy);
|
|
48
48
|
}
|
|
49
49
|
} catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package.mjs","names":[],"sources":["../../src/api/package.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Router } from 'express';\nimport
|
|
1
|
+
{"version":3,"file":"package.mjs","names":[],"sources":["../../src/api/package.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Router } from 'express';\nimport { isNil } from 'lodash-es';\n\nimport type { Auth } from '@verdaccio/auth';\nimport { createAnonymousRemoteUser } from '@verdaccio/config';\nimport { logger } from '@verdaccio/logger';\nimport {\n $NextFunctionVer,\n $RequestExtend,\n $ResponseExtend,\n WebUrls,\n getRequestOptions,\n} from '@verdaccio/middleware';\nimport type { Storage } from '@verdaccio/store';\nimport { getLocalRegistryTarballUri } from '@verdaccio/tarball';\nimport type { Config, RemoteUser, Version } from '@verdaccio/types';\n\nimport { formatAuthor, generateGravatarUrl } from '../author-utils';\nimport { hasLogin, sortByName, sortByTime } from '../web-utils';\n\nexport { $RequestExtend, $ResponseExtend, $NextFunctionVer }; // Was required by other packages\n\nconst getField = (field = 'name') => {\n return field === 'name' || field === 'time' ? field : 'name';\n};\n\nconst getOrder = (order = 'asc') => {\n return order === 'asc';\n};\n\nconst debug = buildDebug('verdaccio:web:api:package');\n\nfunction addPackageWebApi(storage: Storage, auth: Auth, config: Config): Router {\n const isLoginEnabled = hasLogin(config);\n debug('is login enabled: %o', isLoginEnabled);\n const pkgRouter = Router(); /* eslint new-cap: 0 */\n const anonymousRemoteUser: RemoteUser = createAnonymousRemoteUser();\n\n debug('initialized package web api');\n const checkAllow = (name: string, remoteUser: RemoteUser): Promise<boolean> =>\n new Promise((resolve, reject): void => {\n const remoteUserAccess = !isLoginEnabled ? anonymousRemoteUser : remoteUser;\n try {\n auth.allow_access({ packageName: name }, remoteUserAccess, (err, allowed): void => {\n if (err) {\n resolve(false);\n }\n return resolve(allowed as boolean);\n });\n } catch (err: any) {\n reject(err);\n }\n });\n\n async function processPackages(packages: Version[] = [], req): Promise<Version[]> {\n const permissions: Version[] = [];\n const packagesToProcess = packages.slice();\n debug('process packages %o', packagesToProcess);\n const requestOptions = getRequestOptions(req);\n for (const pkg of packagesToProcess) {\n const pkgCopy = { ...pkg };\n pkgCopy.author = formatAuthor(pkg.author);\n try {\n if (await checkAllow(pkg.name, req.remote_user)) {\n if (config.web) {\n // @ts-ignore\n pkgCopy.author.avatar = generateGravatarUrl(pkgCopy.author.email, config.web.gravatar);\n }\n // convert any remote dist to a local reference\n // eg: if the dist points to npmjs, switch to localhost:4873/prefix/etc.tar.gz\n if (!isNil(pkgCopy.dist) && pkgCopy.dist.tarball !== null) {\n pkgCopy.dist.tarball = getLocalRegistryTarballUri(\n pkgCopy.dist.tarball,\n pkg.name,\n requestOptions,\n config?.url_prefix\n );\n }\n permissions.push(pkgCopy);\n }\n } catch (err: any) {\n debug('process packages error %o', err);\n logger.error(\n { name: pkg.name, error: err },\n 'permission process for @{name} has failed: @{error}'\n );\n throw err;\n }\n }\n\n debug('allowed %o packages', permissions.length);\n return permissions;\n }\n\n // Get list of all visible package\n pkgRouter.get(\n WebUrls.packages_all,\n async function (\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n ): Promise<void> {\n debug('hit package web api %o');\n\n try {\n const localPackages: Version[] = await storage.getLocalDatabase();\n\n const field = getField(config?.web?.sort_field);\n const order = getOrder(config?.web?.sort_packages);\n debug('order by %o %o', field, order);\n const pkgs = await processPackages(localPackages, req);\n if (field === 'name') next(sortByName(pkgs, order));\n else next(sortByTime(pkgs, order));\n } catch (error: any) {\n next(error);\n }\n }\n );\n\n return pkgRouter;\n}\n\nexport default addPackageWebApi;\n"],"mappings":";;;;;;;;;;AAuBA,IAAM,YAAY,QAAQ,WAAW;AACnC,QAAO,UAAU,UAAU,UAAU,SAAS,QAAQ;;AAGxD,IAAM,YAAY,QAAQ,UAAU;AAClC,QAAO,UAAU;;AAGnB,IAAM,QAAQ,WAAW,4BAA4B;AAErD,SAAS,iBAAiB,SAAkB,MAAY,QAAwB;CAC9E,MAAM,iBAAiB,SAAS,OAAO;AACvC,OAAM,wBAAwB,eAAe;CAC7C,MAAM,YAAY,QAAQ;CAC1B,MAAM,sBAAkC,2BAA2B;AAEnE,OAAM,8BAA8B;CACpC,MAAM,cAAc,MAAc,eAChC,IAAI,SAAS,SAAS,WAAiB;EACrC,MAAM,mBAAmB,CAAC,iBAAiB,sBAAsB;AACjE,MAAI;AACF,QAAK,aAAa,EAAE,aAAa,MAAM,EAAE,mBAAmB,KAAK,YAAkB;AACjF,QAAI,IACF,SAAQ,MAAM;AAEhB,WAAO,QAAQ,QAAmB;KAClC;WACK,KAAU;AACjB,UAAO,IAAI;;GAEb;CAEJ,eAAe,gBAAgB,WAAsB,EAAE,EAAE,KAAyB;EAChF,MAAM,cAAyB,EAAE;EACjC,MAAM,oBAAoB,SAAS,OAAO;AAC1C,QAAM,uBAAuB,kBAAkB;EAC/C,MAAM,iBAAiB,kBAAkB,IAAI;AAC7C,OAAK,MAAM,OAAO,mBAAmB;GACnC,MAAM,UAAU,EAAE,GAAG,KAAK;AAC1B,WAAQ,SAAS,aAAa,IAAI,OAAO;AACzC,OAAI;AACF,QAAI,MAAM,WAAW,IAAI,MAAM,IAAI,YAAY,EAAE;AAC/C,SAAI,OAAO,IAET,SAAQ,OAAO,SAAS,oBAAoB,QAAQ,OAAO,OAAO,OAAO,IAAI,SAAS;AAIxF,SAAI,CAAC,MAAM,QAAQ,KAAK,IAAI,QAAQ,KAAK,YAAY,KACnD,SAAQ,KAAK,UAAU,2BACrB,QAAQ,KAAK,SACb,IAAI,MACJ,gBACA,QAAQ,WACT;AAEH,iBAAY,KAAK,QAAQ;;YAEpB,KAAU;AACjB,UAAM,6BAA6B,IAAI;AACvC,WAAO,MACL;KAAE,MAAM,IAAI;KAAM,OAAO;KAAK,EAC9B,sDACD;AACD,UAAM;;;AAIV,QAAM,uBAAuB,YAAY,OAAO;AAChD,SAAO;;AAIT,WAAU,IACR,QAAQ,cACR,eACE,KACA,KACA,MACe;AACf,QAAM,yBAAyB;AAE/B,MAAI;GACF,MAAM,gBAA2B,MAAM,QAAQ,kBAAkB;GAEjE,MAAM,QAAQ,SAAS,QAAQ,KAAK,WAAW;GAC/C,MAAM,QAAQ,SAAS,QAAQ,KAAK,cAAc;AAClD,SAAM,kBAAkB,OAAO,MAAM;GACrC,MAAM,OAAO,MAAM,gBAAgB,eAAe,IAAI;AACtD,OAAI,UAAU,OAAQ,MAAK,WAAW,MAAM,MAAM,CAAC;OAC9C,MAAK,WAAW,MAAM,MAAM,CAAC;WAC3B,OAAY;AACnB,QAAK,MAAM;;GAGhB;AAED,QAAO"}
|
package/build/api/search.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
const require_runtime = require("../_virtual/_rolldown/runtime.js");
|
|
2
2
|
let express = require("express");
|
|
3
|
-
let lodash = require("lodash");
|
|
4
|
-
lodash = require_runtime.__toESM(lodash);
|
|
5
3
|
let _verdaccio_core = require("@verdaccio/core");
|
|
6
4
|
let _verdaccio_middleware = require("@verdaccio/middleware");
|
|
7
5
|
let debug = require("debug");
|
|
@@ -49,7 +47,7 @@ function addSearchWebApi(storage, auth) {
|
|
|
49
47
|
});
|
|
50
48
|
next((await Promise.all(data.map((pkgItem) => {
|
|
51
49
|
return checkAccess(pkgItem, auth, req.remote_user);
|
|
52
|
-
}))).filter((i) =>
|
|
50
|
+
}))).filter((i) => i !== null).slice(from, size));
|
|
53
51
|
} catch (err) {
|
|
54
52
|
next(_verdaccio_core.errorUtils.getInternalError(err.message));
|
|
55
53
|
}
|
package/build/api/search.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","names":[],"sources":["../../src/api/search.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Router } from 'express';\nimport
|
|
1
|
+
{"version":3,"file":"search.js","names":[],"sources":["../../src/api/search.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Router } from 'express';\nimport { URLSearchParams } from 'node:url';\n\nimport type { Auth } from '@verdaccio/auth';\nimport { errorUtils } from '@verdaccio/core';\nimport type { SearchQuery } from '@verdaccio/core/src/search-utils';\nimport { WebUrls } from '@verdaccio/middleware';\nimport type { Storage } from '@verdaccio/store';\nimport type { Manifest } from '@verdaccio/types';\n\nimport type { $NextFunctionVer, $RequestExtend, $ResponseExtend } from './package';\n\nconst debug = buildDebug('verdaccio:web:api:search');\n\nfunction checkAccess(pkg: any, auth: any, remoteUser): Promise<Manifest | null> {\n return new Promise((resolve, reject) => {\n auth.allow_access({ packageName: pkg?.package?.name }, remoteUser, function (err, allowed) {\n if (err) {\n if (err.status && String(err.status).match(/^4\\d\\d$/)) {\n // auth plugin returns 4xx user error,\n // that's equivalent of !allowed basically\n allowed = false;\n return resolve(null);\n } else {\n reject(err);\n }\n } else {\n return resolve(allowed ? pkg : null);\n }\n });\n });\n}\n\nfunction addSearchWebApi(storage: Storage, auth: Auth): Router {\n const router = Router(); /* eslint new-cap: 0 */\n router.get(\n WebUrls.search,\n async function (\n req: $RequestExtend,\n _res: $ResponseExtend,\n next: $NextFunctionVer\n ): Promise<void> {\n try {\n const abort = new AbortController();\n req.socket.on('close', function () {\n debug('search web aborted');\n abort.abort();\n });\n const text: string = (req.params.anything as string) ?? '';\n // These values are declared as optimal by npm cli\n // FUTURE: could be overwritten by ui settings.\n const size = 20;\n const from = 0;\n const query: SearchQuery = {\n from: 0,\n maintenance: 0.5,\n popularity: 0.98,\n quality: 0.65,\n size: 20,\n text,\n };\n // @ts-ignore\n const urlParams = new URLSearchParams(query);\n debug('search web init');\n const data = await storage?.search({\n query,\n url: `/-/v1/search?${urlParams.toString()}`,\n abort,\n });\n const checkAccessPromises = await Promise.all(\n data.map((pkgItem) => {\n return checkAccess(pkgItem, auth, req.remote_user);\n })\n );\n\n const final = checkAccessPromises\n .filter((i): i is Manifest => i !== null)\n .slice(from, size);\n\n next(final);\n } catch (err: any) {\n next(errorUtils.getInternalError(err.message));\n }\n }\n );\n return router;\n}\n\nexport default addSearchWebApi;\n"],"mappings":";;;;;;;;AAaA,IAAM,WAAA,GAAA,MAAA,SAAmB,2BAA2B;AAEpD,SAAS,YAAY,KAAU,MAAW,YAAsC;AAC9E,QAAO,IAAI,SAAS,SAAS,WAAW;AACtC,OAAK,aAAa,EAAE,aAAa,KAAK,SAAS,MAAM,EAAE,YAAY,SAAU,KAAK,SAAS;AACzF,OAAI,IACF,KAAI,IAAI,UAAU,OAAO,IAAI,OAAO,CAAC,MAAM,UAAU,EAAE;AAGrD,cAAU;AACV,WAAO,QAAQ,KAAK;SAEpB,QAAO,IAAI;OAGb,QAAO,QAAQ,UAAU,MAAM,KAAK;IAEtC;GACF;;AAGJ,SAAS,gBAAgB,SAAkB,MAAoB;CAC7D,MAAM,UAAA,GAAA,QAAA,SAAiB;AACvB,QAAO,IACL,sBAAA,QAAQ,QACR,eACE,KACA,MACA,MACe;AACf,MAAI;GACF,MAAM,QAAQ,IAAI,iBAAiB;AACnC,OAAI,OAAO,GAAG,SAAS,WAAY;AACjC,YAAM,qBAAqB;AAC3B,UAAM,OAAO;KACb;GACF,MAAM,OAAgB,IAAI,OAAO,YAAuB;GAGxD,MAAM,OAAO;GACb,MAAM,OAAO;GACb,MAAM,QAAqB;IACzB,MAAM;IACN,aAAa;IACb,YAAY;IACZ,SAAS;IACT,MAAM;IACN;IACD;GAED,MAAM,YAAY,IAAI,SAAA,gBAAgB,MAAM;AAC5C,WAAM,kBAAkB;GACxB,MAAM,OAAO,MAAM,SAAS,OAAO;IACjC;IACA,KAAK,gBAAgB,UAAU,UAAU;IACzC;IACD,CAAC;AAWF,SAV4B,MAAM,QAAQ,IACxC,KAAK,KAAK,YAAY;AACpB,WAAO,YAAY,SAAS,MAAM,IAAI,YAAY;KAClD,CACH,EAGE,QAAQ,MAAqB,MAAM,KAAK,CACxC,MAAM,MAAM,KAAK,CAET;WACJ,KAAU;AACjB,QAAK,gBAAA,WAAW,iBAAiB,IAAI,QAAQ,CAAC;;GAGnD;AACD,QAAO"}
|
package/build/api/search.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Router } from "express";
|
|
2
|
-
import _ from "lodash";
|
|
3
2
|
import { errorUtils } from "@verdaccio/core";
|
|
4
3
|
import { WebUrls } from "@verdaccio/middleware";
|
|
5
4
|
import buildDebug from "debug";
|
|
@@ -46,7 +45,7 @@ function addSearchWebApi(storage, auth) {
|
|
|
46
45
|
});
|
|
47
46
|
next((await Promise.all(data.map((pkgItem) => {
|
|
48
47
|
return checkAccess(pkgItem, auth, req.remote_user);
|
|
49
|
-
}))).filter((i) =>
|
|
48
|
+
}))).filter((i) => i !== null).slice(from, size));
|
|
50
49
|
} catch (err) {
|
|
51
50
|
next(errorUtils.getInternalError(err.message));
|
|
52
51
|
}
|
package/build/api/search.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.mjs","names":[],"sources":["../../src/api/search.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Router } from 'express';\nimport
|
|
1
|
+
{"version":3,"file":"search.mjs","names":[],"sources":["../../src/api/search.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Router } from 'express';\nimport { URLSearchParams } from 'node:url';\n\nimport type { Auth } from '@verdaccio/auth';\nimport { errorUtils } from '@verdaccio/core';\nimport type { SearchQuery } from '@verdaccio/core/src/search-utils';\nimport { WebUrls } from '@verdaccio/middleware';\nimport type { Storage } from '@verdaccio/store';\nimport type { Manifest } from '@verdaccio/types';\n\nimport type { $NextFunctionVer, $RequestExtend, $ResponseExtend } from './package';\n\nconst debug = buildDebug('verdaccio:web:api:search');\n\nfunction checkAccess(pkg: any, auth: any, remoteUser): Promise<Manifest | null> {\n return new Promise((resolve, reject) => {\n auth.allow_access({ packageName: pkg?.package?.name }, remoteUser, function (err, allowed) {\n if (err) {\n if (err.status && String(err.status).match(/^4\\d\\d$/)) {\n // auth plugin returns 4xx user error,\n // that's equivalent of !allowed basically\n allowed = false;\n return resolve(null);\n } else {\n reject(err);\n }\n } else {\n return resolve(allowed ? pkg : null);\n }\n });\n });\n}\n\nfunction addSearchWebApi(storage: Storage, auth: Auth): Router {\n const router = Router(); /* eslint new-cap: 0 */\n router.get(\n WebUrls.search,\n async function (\n req: $RequestExtend,\n _res: $ResponseExtend,\n next: $NextFunctionVer\n ): Promise<void> {\n try {\n const abort = new AbortController();\n req.socket.on('close', function () {\n debug('search web aborted');\n abort.abort();\n });\n const text: string = (req.params.anything as string) ?? '';\n // These values are declared as optimal by npm cli\n // FUTURE: could be overwritten by ui settings.\n const size = 20;\n const from = 0;\n const query: SearchQuery = {\n from: 0,\n maintenance: 0.5,\n popularity: 0.98,\n quality: 0.65,\n size: 20,\n text,\n };\n // @ts-ignore\n const urlParams = new URLSearchParams(query);\n debug('search web init');\n const data = await storage?.search({\n query,\n url: `/-/v1/search?${urlParams.toString()}`,\n abort,\n });\n const checkAccessPromises = await Promise.all(\n data.map((pkgItem) => {\n return checkAccess(pkgItem, auth, req.remote_user);\n })\n );\n\n const final = checkAccessPromises\n .filter((i): i is Manifest => i !== null)\n .slice(from, size);\n\n next(final);\n } catch (err: any) {\n next(errorUtils.getInternalError(err.message));\n }\n }\n );\n return router;\n}\n\nexport default addSearchWebApi;\n"],"mappings":";;;;;;AAaA,IAAM,QAAQ,WAAW,2BAA2B;AAEpD,SAAS,YAAY,KAAU,MAAW,YAAsC;AAC9E,QAAO,IAAI,SAAS,SAAS,WAAW;AACtC,OAAK,aAAa,EAAE,aAAa,KAAK,SAAS,MAAM,EAAE,YAAY,SAAU,KAAK,SAAS;AACzF,OAAI,IACF,KAAI,IAAI,UAAU,OAAO,IAAI,OAAO,CAAC,MAAM,UAAU,EAAE;AAGrD,cAAU;AACV,WAAO,QAAQ,KAAK;SAEpB,QAAO,IAAI;OAGb,QAAO,QAAQ,UAAU,MAAM,KAAK;IAEtC;GACF;;AAGJ,SAAS,gBAAgB,SAAkB,MAAoB;CAC7D,MAAM,SAAS,QAAQ;AACvB,QAAO,IACL,QAAQ,QACR,eACE,KACA,MACA,MACe;AACf,MAAI;GACF,MAAM,QAAQ,IAAI,iBAAiB;AACnC,OAAI,OAAO,GAAG,SAAS,WAAY;AACjC,UAAM,qBAAqB;AAC3B,UAAM,OAAO;KACb;GACF,MAAM,OAAgB,IAAI,OAAO,YAAuB;GAGxD,MAAM,OAAO;GACb,MAAM,OAAO;GACb,MAAM,QAAqB;IACzB,MAAM;IACN,aAAa;IACb,YAAY;IACZ,SAAS;IACT,MAAM;IACN;IACD;GAED,MAAM,YAAY,IAAI,gBAAgB,MAAM;AAC5C,SAAM,kBAAkB;GACxB,MAAM,OAAO,MAAM,SAAS,OAAO;IACjC;IACA,KAAK,gBAAgB,UAAU,UAAU;IACzC;IACD,CAAC;AAWF,SAV4B,MAAM,QAAQ,IACxC,KAAK,KAAK,YAAY;AACpB,WAAO,YAAY,SAAS,MAAM,IAAI,YAAY;KAClD,CACH,EAGE,QAAQ,MAAqB,MAAM,KAAK,CACxC,MAAM,MAAM,KAAK,CAET;WACJ,KAAU;AACjB,QAAK,WAAW,iBAAiB,IAAI,QAAQ,CAAC;;GAGnD;AACD,QAAO"}
|
package/build/api/user.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const require_runtime = require("../_virtual/_rolldown/runtime.js");
|
|
2
2
|
let express = require("express");
|
|
3
|
-
let
|
|
4
|
-
lodash = require_runtime.__toESM(lodash);
|
|
3
|
+
let lodash_es = require("lodash-es");
|
|
5
4
|
let _verdaccio_core = require("@verdaccio/core");
|
|
6
5
|
let _verdaccio_middleware = require("@verdaccio/middleware");
|
|
7
6
|
let debug = require("debug");
|
|
@@ -80,7 +79,7 @@ function addUserAuthApi(auth, config, storage) {
|
|
|
80
79
|
});
|
|
81
80
|
});
|
|
82
81
|
if (config?.flags?.changePassword === true) route.put(_verdaccio_middleware.WebUrls.reset_password, (0, _verdaccio_middleware.rateLimit)(config?.userRateLimit), function(req, res, next) {
|
|
83
|
-
if (
|
|
82
|
+
if ((0, lodash_es.isNil)(req.remote_user.name)) {
|
|
84
83
|
res.status(_verdaccio_core.HTTP_STATUS.UNAUTHORIZED);
|
|
85
84
|
return next({ message: _verdaccio_core.API_ERROR.MUST_BE_LOGGED });
|
|
86
85
|
}
|
|
@@ -88,7 +87,7 @@ function addUserAuthApi(auth, config, storage) {
|
|
|
88
87
|
const { name } = req.remote_user;
|
|
89
88
|
if (_verdaccio_core.validationUtils.validatePassword(password.new, config?.server?.passwordValidationRegex) === false) return next(_verdaccio_core.errorUtils.getCode(_verdaccio_core.HTTP_STATUS.BAD_REQUEST, _verdaccio_core.APP_ERROR.PASSWORD_VALIDATION));
|
|
90
89
|
auth.changePassword(name, password.old, password.new, (err, isUpdated) => {
|
|
91
|
-
if (
|
|
90
|
+
if ((0, lodash_es.isNil)(err) && isUpdated) next({ ok: true });
|
|
92
91
|
else return next(_verdaccio_core.errorUtils.getInternalError(_verdaccio_core.API_ERROR.INTERNAL_SERVER_ERROR));
|
|
93
92
|
});
|
|
94
93
|
});
|
package/build/api/user.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.js","names":[],"sources":["../../src/api/user.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport type { Request, Response } from 'express';\nimport { Router } from 'express';\nimport
|
|
1
|
+
{"version":3,"file":"user.js","names":[],"sources":["../../src/api/user.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport type { Request, Response } from 'express';\nimport { Router } from 'express';\nimport { isNil } from 'lodash-es';\n\nimport { type Auth, getApiToken } from '@verdaccio/auth';\nimport type { VerdaccioError } from '@verdaccio/core';\nimport {\n API_ERROR,\n APP_ERROR,\n HEADERS,\n HTTP_STATUS,\n cryptoUtils,\n errorUtils,\n validationUtils,\n} from '@verdaccio/core';\nimport { WebUrls, rateLimit } from '@verdaccio/middleware';\nimport type { Config, JWTSignOptions, RemoteUser } from '@verdaccio/types';\n\nimport type { $NextFunctionVer } from './package';\n\nconst debug = buildDebug('verdaccio:web:api:user');\n\nconst WEB_LOGIN_SESSION_ID = 'web-login-sessionId';\n\nfunction addUserAuthApi(auth: Auth, config: Config, storage: Storage): Router {\n const route = Router(); /* eslint new-cap: 0 */\n route.post(\n WebUrls.user_login,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n const { username, password } = req.body;\n debug('authenticate %o', username);\n auth.authenticate(\n username,\n password,\n async (err: VerdaccioError | null, user?: RemoteUser): Promise<void> => {\n if (err) {\n const errorCode = err.message ? HTTP_STATUS.UNAUTHORIZED : HTTP_STATUS.INTERNAL_ERROR;\n debug('error authenticate %o', errorCode);\n next(errorUtils.getCode(errorCode, err.message));\n } else {\n req.remote_user = user as RemoteUser;\n const jWTSignOptions: JWTSignOptions = config.security.web.sign;\n res.set(HEADERS.CACHE_CONTROL, HEADERS.NO_CACHE);\n next({\n token: await auth.jwtEncrypt(user as RemoteUser, jWTSignOptions),\n username: req.remote_user.name,\n });\n }\n }\n );\n }\n );\n\n if (config?.flags?.createUser === true) {\n route.put(\n WebUrls.user_signup,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n const { name, password, email, sessionId } = req.body;\n debug('login or adduser');\n\n // TOOD: reuse with login.ts file\n if (typeof sessionId !== 'string' || sessionId.length !== 36) {\n debug('sessionId is invalid length: %o', sessionId.length);\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.SESSION_ID_INVALID));\n }\n\n if (!name || !password || !email) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.BAD_DATA));\n }\n\n auth.add_user(name, password, async function (err, user): Promise<void> {\n if (err) {\n if (err.status >= HTTP_STATUS.BAD_REQUEST && err.status < HTTP_STATUS.INTERNAL_ERROR) {\n debug('adduser: error on create user');\n // With npm registering is the same as logging in,\n // and npm accepts only an 409 error.\n // So, changing status code here.\n return next(\n errorUtils.getCode(err.status, err.message) || errorUtils.getConflict(err.message)\n );\n }\n return next(err);\n }\n\n const tokens = await storage.readTokens({ user: sessionId });\n debug('tokens found for sessionId %o: %o', sessionId, tokens.length);\n if (tokens && tokens.length === 1 && tokens[0].key === WEB_LOGIN_SESSION_ID) {\n if (tokens[0].token.length === 0) {\n debug('waiting for authentication');\n // Poll again after short delay\n // TODO: make this configurable (default 5 seconds)\n res.status(HTTP_STATUS.ACCEPTED);\n res.set(HEADERS.RETRY_AFTER, '5');\n res.json({});\n return;\n }\n\n // session token can only be used once\n debug('deleting session token');\n await storage.deleteToken(sessionId, tokens[0].key);\n\n // Check if token has expired\n // TODO: make this configurable (default 2 minutes)\n const tokenCreatedDate = new Date(tokens[0].created);\n const minutesAgo = new Date(Date.now() - 2 * 60 * 1000);\n if (tokenCreatedDate < minutesAgo) {\n debug('session token expired');\n return next(errorUtils.getUnauthorized(API_ERROR.SESSION_TOKEN_EXPIRED));\n }\n\n debug('session token is valid, login successful');\n res.status(HTTP_STATUS.OK);\n res.json({ token: tokens[0].token });\n return;\n }\n\n const token =\n name && password\n ? await getApiToken(auth, config, user as RemoteUser, password)\n : undefined;\n if (token) {\n debug('adduser: new token %o', cryptoUtils.mask(token as string, 4));\n return next({ token, username: name });\n }\n return next(errorUtils.getUnauthorized());\n });\n }\n );\n }\n\n if (config?.flags?.changePassword === true) {\n route.put(\n WebUrls.reset_password,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n if (isNil(req.remote_user.name)) {\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n // FUTURE: update to a more meaningful message\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n\n const { password } = req.body;\n const { name } = req.remote_user;\n\n if (\n validationUtils.validatePassword(\n password.new,\n config?.server?.passwordValidationRegex\n ) === false\n ) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, APP_ERROR.PASSWORD_VALIDATION));\n }\n\n auth.changePassword(name as string, password.old, password.new, (err, isUpdated): void => {\n if (isNil(err) && isUpdated) {\n next({\n ok: true,\n });\n } else {\n return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));\n }\n });\n }\n );\n }\n\n return route;\n}\n\nexport default addUserAuthApi;\n"],"mappings":"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"}
|
package/build/api/user.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Router } from "express";
|
|
2
|
-
import
|
|
2
|
+
import { isNil } from "lodash-es";
|
|
3
3
|
import { API_ERROR, APP_ERROR, HEADERS, HTTP_STATUS, cryptoUtils, errorUtils, validationUtils } from "@verdaccio/core";
|
|
4
4
|
import { WebUrls, rateLimit } from "@verdaccio/middleware";
|
|
5
5
|
import buildDebug from "debug";
|
|
@@ -77,7 +77,7 @@ function addUserAuthApi(auth, config, storage) {
|
|
|
77
77
|
});
|
|
78
78
|
});
|
|
79
79
|
if (config?.flags?.changePassword === true) route.put(WebUrls.reset_password, rateLimit(config?.userRateLimit), function(req, res, next) {
|
|
80
|
-
if (
|
|
80
|
+
if (isNil(req.remote_user.name)) {
|
|
81
81
|
res.status(HTTP_STATUS.UNAUTHORIZED);
|
|
82
82
|
return next({ message: API_ERROR.MUST_BE_LOGGED });
|
|
83
83
|
}
|
|
@@ -85,7 +85,7 @@ function addUserAuthApi(auth, config, storage) {
|
|
|
85
85
|
const { name } = req.remote_user;
|
|
86
86
|
if (validationUtils.validatePassword(password.new, config?.server?.passwordValidationRegex) === false) return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, APP_ERROR.PASSWORD_VALIDATION));
|
|
87
87
|
auth.changePassword(name, password.old, password.new, (err, isUpdated) => {
|
|
88
|
-
if (
|
|
88
|
+
if (isNil(err) && isUpdated) next({ ok: true });
|
|
89
89
|
else return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));
|
|
90
90
|
});
|
|
91
91
|
});
|
package/build/api/user.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.mjs","names":[],"sources":["../../src/api/user.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport type { Request, Response } from 'express';\nimport { Router } from 'express';\nimport
|
|
1
|
+
{"version":3,"file":"user.mjs","names":[],"sources":["../../src/api/user.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport type { Request, Response } from 'express';\nimport { Router } from 'express';\nimport { isNil } from 'lodash-es';\n\nimport { type Auth, getApiToken } from '@verdaccio/auth';\nimport type { VerdaccioError } from '@verdaccio/core';\nimport {\n API_ERROR,\n APP_ERROR,\n HEADERS,\n HTTP_STATUS,\n cryptoUtils,\n errorUtils,\n validationUtils,\n} from '@verdaccio/core';\nimport { WebUrls, rateLimit } from '@verdaccio/middleware';\nimport type { Config, JWTSignOptions, RemoteUser } from '@verdaccio/types';\n\nimport type { $NextFunctionVer } from './package';\n\nconst debug = buildDebug('verdaccio:web:api:user');\n\nconst WEB_LOGIN_SESSION_ID = 'web-login-sessionId';\n\nfunction addUserAuthApi(auth: Auth, config: Config, storage: Storage): Router {\n const route = Router(); /* eslint new-cap: 0 */\n route.post(\n WebUrls.user_login,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n const { username, password } = req.body;\n debug('authenticate %o', username);\n auth.authenticate(\n username,\n password,\n async (err: VerdaccioError | null, user?: RemoteUser): Promise<void> => {\n if (err) {\n const errorCode = err.message ? HTTP_STATUS.UNAUTHORIZED : HTTP_STATUS.INTERNAL_ERROR;\n debug('error authenticate %o', errorCode);\n next(errorUtils.getCode(errorCode, err.message));\n } else {\n req.remote_user = user as RemoteUser;\n const jWTSignOptions: JWTSignOptions = config.security.web.sign;\n res.set(HEADERS.CACHE_CONTROL, HEADERS.NO_CACHE);\n next({\n token: await auth.jwtEncrypt(user as RemoteUser, jWTSignOptions),\n username: req.remote_user.name,\n });\n }\n }\n );\n }\n );\n\n if (config?.flags?.createUser === true) {\n route.put(\n WebUrls.user_signup,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n const { name, password, email, sessionId } = req.body;\n debug('login or adduser');\n\n // TOOD: reuse with login.ts file\n if (typeof sessionId !== 'string' || sessionId.length !== 36) {\n debug('sessionId is invalid length: %o', sessionId.length);\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.SESSION_ID_INVALID));\n }\n\n if (!name || !password || !email) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.BAD_DATA));\n }\n\n auth.add_user(name, password, async function (err, user): Promise<void> {\n if (err) {\n if (err.status >= HTTP_STATUS.BAD_REQUEST && err.status < HTTP_STATUS.INTERNAL_ERROR) {\n debug('adduser: error on create user');\n // With npm registering is the same as logging in,\n // and npm accepts only an 409 error.\n // So, changing status code here.\n return next(\n errorUtils.getCode(err.status, err.message) || errorUtils.getConflict(err.message)\n );\n }\n return next(err);\n }\n\n const tokens = await storage.readTokens({ user: sessionId });\n debug('tokens found for sessionId %o: %o', sessionId, tokens.length);\n if (tokens && tokens.length === 1 && tokens[0].key === WEB_LOGIN_SESSION_ID) {\n if (tokens[0].token.length === 0) {\n debug('waiting for authentication');\n // Poll again after short delay\n // TODO: make this configurable (default 5 seconds)\n res.status(HTTP_STATUS.ACCEPTED);\n res.set(HEADERS.RETRY_AFTER, '5');\n res.json({});\n return;\n }\n\n // session token can only be used once\n debug('deleting session token');\n await storage.deleteToken(sessionId, tokens[0].key);\n\n // Check if token has expired\n // TODO: make this configurable (default 2 minutes)\n const tokenCreatedDate = new Date(tokens[0].created);\n const minutesAgo = new Date(Date.now() - 2 * 60 * 1000);\n if (tokenCreatedDate < minutesAgo) {\n debug('session token expired');\n return next(errorUtils.getUnauthorized(API_ERROR.SESSION_TOKEN_EXPIRED));\n }\n\n debug('session token is valid, login successful');\n res.status(HTTP_STATUS.OK);\n res.json({ token: tokens[0].token });\n return;\n }\n\n const token =\n name && password\n ? await getApiToken(auth, config, user as RemoteUser, password)\n : undefined;\n if (token) {\n debug('adduser: new token %o', cryptoUtils.mask(token as string, 4));\n return next({ token, username: name });\n }\n return next(errorUtils.getUnauthorized());\n });\n }\n );\n }\n\n if (config?.flags?.changePassword === true) {\n route.put(\n WebUrls.reset_password,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n if (isNil(req.remote_user.name)) {\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n // FUTURE: update to a more meaningful message\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n\n const { password } = req.body;\n const { name } = req.remote_user;\n\n if (\n validationUtils.validatePassword(\n password.new,\n config?.server?.passwordValidationRegex\n ) === false\n ) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, APP_ERROR.PASSWORD_VALIDATION));\n }\n\n auth.changePassword(name as string, password.old, password.new, (err, isUpdated): void => {\n if (isNil(err) && isUpdated) {\n next({\n ok: true,\n });\n } else {\n return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));\n }\n });\n }\n );\n }\n\n return route;\n}\n\nexport default addUserAuthApi;\n"],"mappings":"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"}
|
package/build/middleware.js
CHANGED
|
@@ -2,8 +2,7 @@ const require_runtime = require("./_virtual/_rolldown/runtime.js");
|
|
|
2
2
|
const require_index = require("./api/index.js");
|
|
3
3
|
let express = require("express");
|
|
4
4
|
express = require_runtime.__toESM(express);
|
|
5
|
-
let
|
|
6
|
-
lodash = require_runtime.__toESM(lodash);
|
|
5
|
+
let lodash_es = require("lodash-es");
|
|
7
6
|
let _verdaccio_core = require("@verdaccio/core");
|
|
8
7
|
let _verdaccio_loaders = require("@verdaccio/loaders");
|
|
9
8
|
let _verdaccio_logger = require("@verdaccio/logger");
|
|
@@ -11,7 +10,7 @@ let _verdaccio_middleware = require("@verdaccio/middleware");
|
|
|
11
10
|
//#region src/middleware.ts
|
|
12
11
|
var DEFAULT_PLUGIN_UI_THEME = "@verdaccio/ui-theme";
|
|
13
12
|
async function loadTheme(config) {
|
|
14
|
-
if (
|
|
13
|
+
if ((0, lodash_es.isNil)(config.theme) === false) {
|
|
15
14
|
const plugin = await (0, _verdaccio_loaders.asyncLoadPlugin)(config.theme, {
|
|
16
15
|
config,
|
|
17
16
|
logger: _verdaccio_logger.logger
|
|
@@ -25,7 +24,7 @@ async function loadTheme(config) {
|
|
|
25
24
|
return plugin.staticPath && plugin.manifest && plugin.manifestFiles;
|
|
26
25
|
}, false, config.server?.pluginPrefix ?? _verdaccio_core.PLUGIN_UI_PREFIX, _verdaccio_core.PLUGIN_CATEGORY.THEME);
|
|
27
26
|
if (plugin.length > 1) _verdaccio_logger.logger.warn("multiple ui themes are not supported; only the first plugin is used");
|
|
28
|
-
return
|
|
27
|
+
return (0, lodash_es.head)(plugin);
|
|
29
28
|
}
|
|
30
29
|
}
|
|
31
30
|
var middleware_default = async (config, auth, storage, logger) => {
|
package/build/middleware.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","names":[],"sources":["../src/middleware.ts"],"sourcesContent":["import express from 'express';\nimport
|
|
1
|
+
{"version":3,"file":"middleware.js","names":[],"sources":["../src/middleware.ts"],"sourcesContent":["import express from 'express';\nimport { head, isNil } from 'lodash-es';\n\nimport { PLUGIN_CATEGORY, PLUGIN_UI_PREFIX } from '@verdaccio/core';\nimport { asyncLoadPlugin } from '@verdaccio/loaders';\nimport { logger } from '@verdaccio/logger';\nimport { webMiddleware } from '@verdaccio/middleware';\n\nimport webEndpointsApi from './api';\n\nexport const DEFAULT_PLUGIN_UI_THEME = '@verdaccio/ui-theme';\n\nexport async function loadTheme(config: any) {\n if (isNil(config.theme) === false) {\n const plugin = await asyncLoadPlugin(\n config.theme,\n { config, logger },\n // TODO: add types { staticPath: string; manifest: unknown; manifestFiles: unknown }\n function (plugin: any) {\n /**\n *\n - `staticPath`: is the same data returned in Verdaccio 5.\n - `manifest`: A manifest object.\n - `manifestFiles`: A object with one property `js` and the array (order matters) of the manifest id to be loaded in the template dynamically.\n */\n return plugin.staticPath && plugin.manifest && plugin.manifestFiles;\n },\n false,\n config.server?.pluginPrefix ?? PLUGIN_UI_PREFIX,\n PLUGIN_CATEGORY.THEME\n );\n if (plugin.length > 1) {\n logger.warn('multiple ui themes are not supported; only the first plugin is used');\n }\n\n return head(plugin);\n }\n}\n\nexport default async (config, auth, storage, logger) => {\n let pluginOptions = await loadTheme(config);\n if (!pluginOptions) {\n pluginOptions = require(DEFAULT_PLUGIN_UI_THEME)(config.web);\n logger.info(\n { name: DEFAULT_PLUGIN_UI_THEME, pluginCategory: PLUGIN_CATEGORY.THEME },\n 'plugin @{name} successfully loaded (@{pluginCategory})'\n );\n }\n\n const router = express.Router();\n // load application\n router.use(\n webMiddleware(\n config,\n {\n tokenMiddleware: auth.webUIJWTmiddleware(),\n webEndpointsApi: webEndpointsApi(auth, storage, config),\n },\n pluginOptions\n )\n );\n return router;\n};\n"],"mappings":";;;;;;;;;;AAUA,IAAa,0BAA0B;AAEvC,eAAsB,UAAU,QAAa;AAC3C,MAAA,GAAA,UAAA,OAAU,OAAO,MAAM,KAAK,OAAO;EACjC,MAAM,SAAS,OAAA,GAAA,mBAAA,iBACb,OAAO,OACP;GAAE;GAAQ,QAAA,kBAAA;GAAQ,EAElB,SAAU,QAAa;;;;;;;AAOrB,UAAO,OAAO,cAAc,OAAO,YAAY,OAAO;KAExD,OACA,OAAO,QAAQ,gBAAgB,gBAAA,kBAC/B,gBAAA,gBAAgB,MACjB;AACD,MAAI,OAAO,SAAS,EAClB,mBAAA,OAAO,KAAK,sEAAsE;AAGpF,UAAA,GAAA,UAAA,MAAY,OAAO;;;AAIvB,IAAA,qBAAe,OAAO,QAAQ,MAAM,SAAS,WAAW;CACtD,IAAI,gBAAgB,MAAM,UAAU,OAAO;AAC3C,KAAI,CAAC,eAAe;AAClB,kBAAgB,QAAQ,wBAAwB,CAAC,OAAO,IAAI;AAC5D,SAAO,KACL;GAAE,MAAM;GAAyB,gBAAgB,gBAAA,gBAAgB;GAAO,EACxE,yDACD;;CAGH,MAAM,SAAS,QAAA,QAAQ,QAAQ;AAE/B,QAAO,KAAA,GAAA,sBAAA,eAEH,QACA;EACE,iBAAiB,KAAK,oBAAoB;EAC1C,iBAAiB,cAAA,QAAgB,MAAM,SAAS,OAAO;EACxD,EACD,cACD,CACF;AACD,QAAO"}
|
package/build/middleware.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __require } from "./_virtual/_rolldown/runtime.mjs";
|
|
2
2
|
import api_default from "./api/index.mjs";
|
|
3
3
|
import express from "express";
|
|
4
|
-
import
|
|
4
|
+
import { head, isNil } from "lodash-es";
|
|
5
5
|
import { PLUGIN_CATEGORY, PLUGIN_UI_PREFIX } from "@verdaccio/core";
|
|
6
6
|
import { asyncLoadPlugin } from "@verdaccio/loaders";
|
|
7
7
|
import { logger } from "@verdaccio/logger";
|
|
@@ -9,7 +9,7 @@ import { webMiddleware } from "@verdaccio/middleware";
|
|
|
9
9
|
//#region src/middleware.ts
|
|
10
10
|
var DEFAULT_PLUGIN_UI_THEME = "@verdaccio/ui-theme";
|
|
11
11
|
async function loadTheme(config) {
|
|
12
|
-
if (
|
|
12
|
+
if (isNil(config.theme) === false) {
|
|
13
13
|
const plugin = await asyncLoadPlugin(config.theme, {
|
|
14
14
|
config,
|
|
15
15
|
logger
|
|
@@ -23,7 +23,7 @@ async function loadTheme(config) {
|
|
|
23
23
|
return plugin.staticPath && plugin.manifest && plugin.manifestFiles;
|
|
24
24
|
}, false, config.server?.pluginPrefix ?? PLUGIN_UI_PREFIX, PLUGIN_CATEGORY.THEME);
|
|
25
25
|
if (plugin.length > 1) logger.warn("multiple ui themes are not supported; only the first plugin is used");
|
|
26
|
-
return
|
|
26
|
+
return head(plugin);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
var middleware_default = async (config, auth, storage, logger) => {
|
package/build/middleware.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.mjs","names":[],"sources":["../src/middleware.ts"],"sourcesContent":["import express from 'express';\nimport
|
|
1
|
+
{"version":3,"file":"middleware.mjs","names":[],"sources":["../src/middleware.ts"],"sourcesContent":["import express from 'express';\nimport { head, isNil } from 'lodash-es';\n\nimport { PLUGIN_CATEGORY, PLUGIN_UI_PREFIX } from '@verdaccio/core';\nimport { asyncLoadPlugin } from '@verdaccio/loaders';\nimport { logger } from '@verdaccio/logger';\nimport { webMiddleware } from '@verdaccio/middleware';\n\nimport webEndpointsApi from './api';\n\nexport const DEFAULT_PLUGIN_UI_THEME = '@verdaccio/ui-theme';\n\nexport async function loadTheme(config: any) {\n if (isNil(config.theme) === false) {\n const plugin = await asyncLoadPlugin(\n config.theme,\n { config, logger },\n // TODO: add types { staticPath: string; manifest: unknown; manifestFiles: unknown }\n function (plugin: any) {\n /**\n *\n - `staticPath`: is the same data returned in Verdaccio 5.\n - `manifest`: A manifest object.\n - `manifestFiles`: A object with one property `js` and the array (order matters) of the manifest id to be loaded in the template dynamically.\n */\n return plugin.staticPath && plugin.manifest && plugin.manifestFiles;\n },\n false,\n config.server?.pluginPrefix ?? PLUGIN_UI_PREFIX,\n PLUGIN_CATEGORY.THEME\n );\n if (plugin.length > 1) {\n logger.warn('multiple ui themes are not supported; only the first plugin is used');\n }\n\n return head(plugin);\n }\n}\n\nexport default async (config, auth, storage, logger) => {\n let pluginOptions = await loadTheme(config);\n if (!pluginOptions) {\n pluginOptions = require(DEFAULT_PLUGIN_UI_THEME)(config.web);\n logger.info(\n { name: DEFAULT_PLUGIN_UI_THEME, pluginCategory: PLUGIN_CATEGORY.THEME },\n 'plugin @{name} successfully loaded (@{pluginCategory})'\n );\n }\n\n const router = express.Router();\n // load application\n router.use(\n webMiddleware(\n config,\n {\n tokenMiddleware: auth.webUIJWTmiddleware(),\n webEndpointsApi: webEndpointsApi(auth, storage, config),\n },\n pluginOptions\n )\n );\n return router;\n};\n"],"mappings":";;;;;;;;;AAUA,IAAa,0BAA0B;AAEvC,eAAsB,UAAU,QAAa;AAC3C,KAAI,MAAM,OAAO,MAAM,KAAK,OAAO;EACjC,MAAM,SAAS,MAAM,gBACnB,OAAO,OACP;GAAE;GAAQ;GAAQ,EAElB,SAAU,QAAa;;;;;;;AAOrB,UAAO,OAAO,cAAc,OAAO,YAAY,OAAO;KAExD,OACA,OAAO,QAAQ,gBAAgB,kBAC/B,gBAAgB,MACjB;AACD,MAAI,OAAO,SAAS,EAClB,QAAO,KAAK,sEAAsE;AAGpF,SAAO,KAAK,OAAO;;;AAIvB,IAAA,qBAAe,OAAO,QAAQ,MAAM,SAAS,WAAW;CACtD,IAAI,gBAAgB,MAAM,UAAU,OAAO;AAC3C,KAAI,CAAC,eAAe;AAClB,kBAAA,UAAwB,wBAAwB,CAAC,OAAO,IAAI;AAC5D,SAAO,KACL;GAAE,MAAM;GAAyB,gBAAgB,gBAAgB;GAAO,EACxE,yDACD;;CAGH,MAAM,SAAS,QAAQ,QAAQ;AAE/B,QAAO,IACL,cACE,QACA;EACE,iBAAiB,KAAK,oBAAoB;EAC1C,iBAAiB,YAAgB,MAAM,SAAS,OAAO;EACxD,EACD,cACD,CACF;AACD,QAAO"}
|
package/build/web-utils.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
let
|
|
3
|
-
lodash = require_runtime.__toESM(lodash);
|
|
1
|
+
require("./_virtual/_rolldown/runtime.js");
|
|
2
|
+
let lodash_es = require("lodash-es");
|
|
4
3
|
//#region src/web-utils.ts
|
|
5
4
|
function hasLogin(config) {
|
|
6
|
-
return
|
|
5
|
+
return (0, lodash_es.isNil)(config?.web?.login) || config?.web?.login === true;
|
|
7
6
|
}
|
|
8
7
|
function sortByName(packages, orderAscending = true) {
|
|
9
8
|
return packages.slice().sort(function(a, b) {
|
|
@@ -21,7 +20,7 @@ function addScope(scope, packageName) {
|
|
|
21
20
|
return `@${scope}/${packageName}`;
|
|
22
21
|
}
|
|
23
22
|
function deleteProperties(propertiesToDelete, objectItem) {
|
|
24
|
-
|
|
23
|
+
(0, lodash_es.forEach)(propertiesToDelete, (property) => {
|
|
25
24
|
delete objectItem[property];
|
|
26
25
|
});
|
|
27
26
|
return objectItem;
|
package/build/web-utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-utils.js","names":[],"sources":["../src/web-utils.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"web-utils.js","names":[],"sources":["../src/web-utils.ts"],"sourcesContent":["import { forEach, isNil } from 'lodash-es';\n\nimport type { ConfigYaml, Manifest } from '@verdaccio/types';\n\nexport function hasLogin(config: ConfigYaml) {\n return isNil(config?.web?.login) || config?.web?.login === true;\n}\n\nexport function sortByName(packages: any[], orderAscending: boolean | void = true): string[] {\n return packages.slice().sort(function (a, b): number {\n const comparatorNames = a.name.toLowerCase() < b.name.toLowerCase();\n return orderAscending ? (comparatorNames ? -1 : 1) : comparatorNames ? 1 : -1;\n });\n}\n\nexport function sortByTime(packages: any[], orderAscending: boolean | void = true): string[] {\n return packages.slice().sort(function (a, b): number {\n const comparatorTime = a.time < b.time;\n return orderAscending ? (comparatorTime ? -1 : 1) : comparatorTime ? 1 : -1;\n });\n}\n\nexport function addScope(scope: string, packageName: string): string {\n return `@${scope}/${packageName}`;\n}\n\nexport function deleteProperties(propertiesToDelete: string[], objectItem: any): any {\n forEach(propertiesToDelete, (property): any => {\n delete objectItem[property];\n });\n\n return objectItem;\n}\n\nexport function isVersionValid(packageMeta: Manifest, packageVersion: string): boolean {\n const hasVersion = typeof packageVersion !== 'undefined';\n if (!hasVersion) {\n return false;\n }\n\n const hasMatchVersion = Object.keys(packageMeta.versions).includes(packageVersion);\n return hasMatchVersion;\n}\n"],"mappings":";;;AAIA,SAAgB,SAAS,QAAoB;AAC3C,SAAA,GAAA,UAAA,OAAa,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,UAAU;;AAG7D,SAAgB,WAAW,UAAiB,iBAAiC,MAAgB;AAC3F,QAAO,SAAS,OAAO,CAAC,KAAK,SAAU,GAAG,GAAW;EACnD,MAAM,kBAAkB,EAAE,KAAK,aAAa,GAAG,EAAE,KAAK,aAAa;AACnE,SAAO,iBAAkB,kBAAkB,KAAK,IAAK,kBAAkB,IAAI;GAC3E;;AAGJ,SAAgB,WAAW,UAAiB,iBAAiC,MAAgB;AAC3F,QAAO,SAAS,OAAO,CAAC,KAAK,SAAU,GAAG,GAAW;EACnD,MAAM,iBAAiB,EAAE,OAAO,EAAE;AAClC,SAAO,iBAAkB,iBAAiB,KAAK,IAAK,iBAAiB,IAAI;GACzE;;AAGJ,SAAgB,SAAS,OAAe,aAA6B;AACnE,QAAO,IAAI,MAAM,GAAG;;AAGtB,SAAgB,iBAAiB,oBAA8B,YAAsB;AACnF,EAAA,GAAA,UAAA,SAAQ,qBAAqB,aAAkB;AAC7C,SAAO,WAAW;GAClB;AAEF,QAAO;;AAGT,SAAgB,eAAe,aAAuB,gBAAiC;AAErF,KAAI,EADe,OAAO,mBAAmB,aAE3C,QAAO;AAIT,QADwB,OAAO,KAAK,YAAY,SAAS,CAAC,SAAS,eAAe"}
|
package/build/web-utils.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { forEach, isNil } from "lodash-es";
|
|
2
2
|
//#region src/web-utils.ts
|
|
3
3
|
function hasLogin(config) {
|
|
4
|
-
return
|
|
4
|
+
return isNil(config?.web?.login) || config?.web?.login === true;
|
|
5
5
|
}
|
|
6
6
|
function sortByName(packages, orderAscending = true) {
|
|
7
7
|
return packages.slice().sort(function(a, b) {
|
|
@@ -19,7 +19,7 @@ function addScope(scope, packageName) {
|
|
|
19
19
|
return `@${scope}/${packageName}`;
|
|
20
20
|
}
|
|
21
21
|
function deleteProperties(propertiesToDelete, objectItem) {
|
|
22
|
-
|
|
22
|
+
forEach(propertiesToDelete, (property) => {
|
|
23
23
|
delete objectItem[property];
|
|
24
24
|
});
|
|
25
25
|
return objectItem;
|
package/build/web-utils.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-utils.mjs","names":[],"sources":["../src/web-utils.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"web-utils.mjs","names":[],"sources":["../src/web-utils.ts"],"sourcesContent":["import { forEach, isNil } from 'lodash-es';\n\nimport type { ConfigYaml, Manifest } from '@verdaccio/types';\n\nexport function hasLogin(config: ConfigYaml) {\n return isNil(config?.web?.login) || config?.web?.login === true;\n}\n\nexport function sortByName(packages: any[], orderAscending: boolean | void = true): string[] {\n return packages.slice().sort(function (a, b): number {\n const comparatorNames = a.name.toLowerCase() < b.name.toLowerCase();\n return orderAscending ? (comparatorNames ? -1 : 1) : comparatorNames ? 1 : -1;\n });\n}\n\nexport function sortByTime(packages: any[], orderAscending: boolean | void = true): string[] {\n return packages.slice().sort(function (a, b): number {\n const comparatorTime = a.time < b.time;\n return orderAscending ? (comparatorTime ? -1 : 1) : comparatorTime ? 1 : -1;\n });\n}\n\nexport function addScope(scope: string, packageName: string): string {\n return `@${scope}/${packageName}`;\n}\n\nexport function deleteProperties(propertiesToDelete: string[], objectItem: any): any {\n forEach(propertiesToDelete, (property): any => {\n delete objectItem[property];\n });\n\n return objectItem;\n}\n\nexport function isVersionValid(packageMeta: Manifest, packageVersion: string): boolean {\n const hasVersion = typeof packageVersion !== 'undefined';\n if (!hasVersion) {\n return false;\n }\n\n const hasMatchVersion = Object.keys(packageMeta.versions).includes(packageVersion);\n return hasMatchVersion;\n}\n"],"mappings":";;AAIA,SAAgB,SAAS,QAAoB;AAC3C,QAAO,MAAM,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,UAAU;;AAG7D,SAAgB,WAAW,UAAiB,iBAAiC,MAAgB;AAC3F,QAAO,SAAS,OAAO,CAAC,KAAK,SAAU,GAAG,GAAW;EACnD,MAAM,kBAAkB,EAAE,KAAK,aAAa,GAAG,EAAE,KAAK,aAAa;AACnE,SAAO,iBAAkB,kBAAkB,KAAK,IAAK,kBAAkB,IAAI;GAC3E;;AAGJ,SAAgB,WAAW,UAAiB,iBAAiC,MAAgB;AAC3F,QAAO,SAAS,OAAO,CAAC,KAAK,SAAU,GAAG,GAAW;EACnD,MAAM,iBAAiB,EAAE,OAAO,EAAE;AAClC,SAAO,iBAAkB,iBAAiB,KAAK,IAAK,iBAAiB,IAAI;GACzE;;AAGJ,SAAgB,SAAS,OAAe,aAA6B;AACnE,QAAO,IAAI,MAAM,GAAG;;AAGtB,SAAgB,iBAAiB,oBAA8B,YAAsB;AACnF,SAAQ,qBAAqB,aAAkB;AAC7C,SAAO,WAAW;GAClB;AAEF,QAAO;;AAGT,SAAgB,eAAe,aAAuB,gBAAiC;AAErF,KAAI,EADe,OAAO,mBAAmB,aAE3C,QAAO;AAIT,QADwB,OAAO,KAAK,YAAY,SAAS,CAAC,SAAS,eAAe"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/web",
|
|
3
|
-
"version": "9.0.0-next-9.
|
|
3
|
+
"version": "9.0.0-next-9.8",
|
|
4
4
|
"description": "Verdaccio Web Middleware",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -28,22 +28,23 @@
|
|
|
28
28
|
},
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@verdaccio/auth": "9.0.0-next-9.
|
|
32
|
-
"@verdaccio/config": "9.0.0-next-9.
|
|
33
|
-
"@verdaccio/core": "9.0.0-next-9.
|
|
34
|
-
"@verdaccio/loaders": "9.0.0-next-9.
|
|
35
|
-
"@verdaccio/logger": "9.0.0-next-9.
|
|
36
|
-
"@verdaccio/middleware": "9.0.0-next-9.
|
|
37
|
-
"@verdaccio/store": "9.0.0-next-9.
|
|
38
|
-
"@verdaccio/tarball": "14.0.0-next-9.
|
|
31
|
+
"@verdaccio/auth": "9.0.0-next-9.8",
|
|
32
|
+
"@verdaccio/config": "9.0.0-next-9.8",
|
|
33
|
+
"@verdaccio/core": "9.0.0-next-9.8",
|
|
34
|
+
"@verdaccio/loaders": "9.0.0-next-9.8",
|
|
35
|
+
"@verdaccio/logger": "9.0.0-next-9.8",
|
|
36
|
+
"@verdaccio/middleware": "9.0.0-next-9.8",
|
|
37
|
+
"@verdaccio/store": "9.0.0-next-9.8",
|
|
38
|
+
"@verdaccio/tarball": "14.0.0-next-9.8",
|
|
39
39
|
"debug": "4.4.3",
|
|
40
40
|
"express": "5.2.1",
|
|
41
|
-
"lodash": "4.17.23"
|
|
41
|
+
"lodash-es": "4.17.23"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@verdaccio/api": "9.0.0-next-9.
|
|
45
|
-
"@verdaccio/test-helper": "5.0.0-next-9.
|
|
46
|
-
"@verdaccio/types": "14.0.0-next-9.
|
|
44
|
+
"@verdaccio/api": "9.0.0-next-9.8",
|
|
45
|
+
"@verdaccio/test-helper": "5.0.0-next-9.8",
|
|
46
|
+
"@verdaccio/types": "14.0.0-next-9.4",
|
|
47
|
+
"@types/lodash-es": "4.17.12",
|
|
47
48
|
"jsdom": "28.1.0",
|
|
48
49
|
"supertest": "7.1.4",
|
|
49
50
|
"vitest": "4.1.0"
|