@verdaccio/api 6.0.0-6-next.30 → 6.0.0-6-next.32
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/CHANGELOG.md +95 -0
- package/build/dist-tags.d.ts +2 -2
- package/build/dist-tags.js.map +1 -1
- package/build/index.d.ts +2 -2
- package/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/package.d.ts +2 -2
- package/build/package.js +8 -1
- package/build/package.js.map +1 -1
- package/build/publish.d.ts +3 -3
- package/build/publish.js +15 -21
- package/build/publish.js.map +1 -1
- package/build/user.d.ts +2 -2
- package/build/user.js +14 -9
- package/build/user.js.map +1 -1
- package/build/v1/profile.d.ts +3 -2
- package/build/v1/profile.js +5 -5
- package/build/v1/profile.js.map +1 -1
- package/build/v1/search.d.ts +2 -2
- package/build/v1/search.js.map +1 -1
- package/build/v1/token.d.ts +2 -2
- package/build/v1/token.js.map +1 -1
- package/package.json +12 -12
- package/src/dist-tags.ts +2 -2
- package/src/index.ts +3 -3
- package/src/package.ts +11 -4
- package/src/publish.ts +12 -17
- package/src/user.ts +21 -13
- package/src/v1/profile.ts +18 -6
- package/src/v1/search.ts +2 -2
- package/src/v1/token.ts +4 -4
- package/test/integration/_helper.ts +2 -1
- package/test/integration/package.spec.ts +1 -1
- package/test/integration/publish.spec.ts +5 -2
- package/test/integration/user.spec.ts +139 -234
- package/test/integration/user.jwt.spec.ts +0 -78
package/build/v1/profile.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profile.js","names":["route","auth","buildProfile","name","tfa","email","email_verified","created","updated","cidr_whitelist","fullname","get","req","res","next","_","isNil","remote_user","status","HTTP_STATUS","UNAUTHORIZED","message","API_ERROR","MUST_BE_LOGGED","post","password","body","validatePassword","new","errorUtils","getCode","PASSWORD_SHORT","changePassword","old","err","isUpdated","isNull","getConflict","getInternalError","INTERNAL_SERVER_ERROR","SERVICE_UNAVAILABLE","SUPPORT_ERRORS","TFA_DISABLED","INTERNAL_ERROR","APP_ERROR","PROFILE_ERROR"],"sources":["../../src/v1/profile.ts"],"sourcesContent":["import { Response, Router } from 'express';\nimport _ from 'lodash';\n\nimport {
|
|
1
|
+
{"version":3,"file":"profile.js","names":["route","auth","config","buildProfile","name","tfa","email","email_verified","created","updated","cidr_whitelist","fullname","get","req","res","next","_","isNil","remote_user","status","HTTP_STATUS","UNAUTHORIZED","message","API_ERROR","MUST_BE_LOGGED","post","password","body","validatioUtils","validatePassword","new","serverSettings","passwordValidationRegex","errorUtils","getCode","PASSWORD_SHORT","changePassword","old","err","isUpdated","isNull","getConflict","getInternalError","INTERNAL_SERVER_ERROR","SERVICE_UNAVAILABLE","SUPPORT_ERRORS","TFA_DISABLED","INTERNAL_ERROR","APP_ERROR","PROFILE_ERROR"],"sources":["../../src/v1/profile.ts"],"sourcesContent":["import { Response, Router } from 'express';\nimport _ from 'lodash';\n\nimport { Auth } from '@verdaccio/auth';\nimport {\n API_ERROR,\n APP_ERROR,\n HTTP_STATUS,\n SUPPORT_ERRORS,\n errorUtils,\n validatioUtils,\n} from '@verdaccio/core';\nimport { Config } from '@verdaccio/types';\n\nimport { $NextFunctionVer, $RequestExtend } from '../../types/custom';\n\nexport interface Profile {\n tfa: boolean;\n name: string;\n email: string;\n email_verified: boolean;\n created: string;\n updated: string;\n cidr_whitelist: string[] | null;\n fullname: string;\n}\n\nexport default function (route: Router, auth: Auth, config: Config): void {\n function buildProfile(name: string): Profile {\n return {\n tfa: false,\n name,\n email: '',\n email_verified: false,\n created: '',\n updated: '',\n cidr_whitelist: null,\n fullname: '',\n };\n }\n\n route.get(\n '/-/npm/v1/user',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n if (_.isNil(req.remote_user.name) === false) {\n return next(buildProfile(req.remote_user.name));\n }\n\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n );\n\n route.post(\n '/-/npm/v1/user',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n if (_.isNil(req.remote_user.name)) {\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n\n const { password, tfa } = req.body;\n const { name } = req.remote_user;\n\n if (_.isNil(password) === false) {\n if (\n validatioUtils.validatePassword(\n password.new,\n config?.serverSettings?.passwordValidationRegex\n ) === false\n ) {\n /* eslint new-cap:off */\n return next(errorUtils.getCode(HTTP_STATUS.UNAUTHORIZED, API_ERROR.PASSWORD_SHORT));\n /* eslint new-cap:off */\n }\n\n auth.changePassword(\n name,\n password.old,\n password.new,\n (err, isUpdated): $NextFunctionVer => {\n if (_.isNull(err) === false) {\n return next(\n errorUtils.getCode(err.status, err.message) || errorUtils.getConflict(err.message)\n );\n }\n\n if (isUpdated) {\n return next(buildProfile(req.remote_user.name));\n }\n return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));\n }\n );\n } else if (_.isNil(tfa) === false) {\n return next(\n errorUtils.getCode(HTTP_STATUS.SERVICE_UNAVAILABLE, SUPPORT_ERRORS.TFA_DISABLED)\n );\n } else {\n return next(errorUtils.getCode(HTTP_STATUS.INTERNAL_ERROR, APP_ERROR.PROFILE_ERROR));\n }\n }\n );\n}\n"],"mappings":";;;;;;;AACA;;AAGA;;;;AAuBe,kBAAUA,KAAV,EAAyBC,IAAzB,EAAqCC,MAArC,EAA2D;EACxE,SAASC,YAAT,CAAsBC,IAAtB,EAA6C;IAC3C,OAAO;MACLC,GAAG,EAAE,KADA;MAELD,IAFK;MAGLE,KAAK,EAAE,EAHF;MAILC,cAAc,EAAE,KAJX;MAKLC,OAAO,EAAE,EALJ;MAMLC,OAAO,EAAE,EANJ;MAOLC,cAAc,EAAE,IAPX;MAQLC,QAAQ,EAAE;IARL,CAAP;EAUD;;EAEDX,KAAK,CAACY,GAAN,CACE,gBADF,EAEE,UAAUC,GAAV,EAA+BC,GAA/B,EAA8CC,IAA9C,EAA4E;IAC1E,IAAIC,eAAA,CAAEC,KAAF,CAAQJ,GAAG,CAACK,WAAJ,CAAgBd,IAAxB,MAAkC,KAAtC,EAA6C;MAC3C,OAAOW,IAAI,CAACZ,YAAY,CAACU,GAAG,CAACK,WAAJ,CAAgBd,IAAjB,CAAb,CAAX;IACD;;IAEDU,GAAG,CAACK,MAAJ,CAAWC,iBAAA,CAAYC,YAAvB;IACA,OAAON,IAAI,CAAC;MACVO,OAAO,EAAEC,eAAA,CAAUC;IADT,CAAD,CAAX;EAGD,CAXH;EAcAxB,KAAK,CAACyB,IAAN,CACE,gBADF,EAEE,UAAUZ,GAAV,EAA+BC,GAA/B,EAA8CC,IAA9C,EAA4E;IAC1E,IAAIC,eAAA,CAAEC,KAAF,CAAQJ,GAAG,CAACK,WAAJ,CAAgBd,IAAxB,CAAJ,EAAmC;MACjCU,GAAG,CAACK,MAAJ,CAAWC,iBAAA,CAAYC,YAAvB;MACA,OAAON,IAAI,CAAC;QACVO,OAAO,EAAEC,eAAA,CAAUC;MADT,CAAD,CAAX;IAGD;;IAED,MAAM;MAAEE,QAAF;MAAYrB;IAAZ,IAAoBQ,GAAG,CAACc,IAA9B;IACA,MAAM;MAAEvB;IAAF,IAAWS,GAAG,CAACK,WAArB;;IAEA,IAAIF,eAAA,CAAEC,KAAF,CAAQS,QAAR,MAAsB,KAA1B,EAAiC;MAAA;;MAC/B,IACEE,oBAAA,CAAeC,gBAAf,CACEH,QAAQ,CAACI,GADX,EAEE5B,MAFF,aAEEA,MAFF,gDAEEA,MAAM,CAAE6B,cAFV,0DAEE,sBAAwBC,uBAF1B,MAGM,KAJR,EAKE;QACA;QACA,OAAOjB,IAAI,CAACkB,gBAAA,CAAWC,OAAX,CAAmBd,iBAAA,CAAYC,YAA/B,EAA6CE,eAAA,CAAUY,cAAvD,CAAD,CAAX;QACA;MACD;;MAEDlC,IAAI,CAACmC,cAAL,CACEhC,IADF,EAEEsB,QAAQ,CAACW,GAFX,EAGEX,QAAQ,CAACI,GAHX,EAIE,CAACQ,GAAD,EAAMC,SAAN,KAAsC;QACpC,IAAIvB,eAAA,CAAEwB,MAAF,CAASF,GAAT,MAAkB,KAAtB,EAA6B;UAC3B,OAAOvB,IAAI,CACTkB,gBAAA,CAAWC,OAAX,CAAmBI,GAAG,CAACnB,MAAvB,EAA+BmB,GAAG,CAAChB,OAAnC,KAA+CW,gBAAA,CAAWQ,WAAX,CAAuBH,GAAG,CAAChB,OAA3B,CADtC,CAAX;QAGD;;QAED,IAAIiB,SAAJ,EAAe;UACb,OAAOxB,IAAI,CAACZ,YAAY,CAACU,GAAG,CAACK,WAAJ,CAAgBd,IAAjB,CAAb,CAAX;QACD;;QACD,OAAOW,IAAI,CAACkB,gBAAA,CAAWS,gBAAX,CAA4BnB,eAAA,CAAUoB,qBAAtC,CAAD,CAAX;MACD,CAfH;IAiBD,CA7BD,MA6BO,IAAI3B,eAAA,CAAEC,KAAF,CAAQZ,GAAR,MAAiB,KAArB,EAA4B;MACjC,OAAOU,IAAI,CACTkB,gBAAA,CAAWC,OAAX,CAAmBd,iBAAA,CAAYwB,mBAA/B,EAAoDC,oBAAA,CAAeC,YAAnE,CADS,CAAX;IAGD,CAJM,MAIA;MACL,OAAO/B,IAAI,CAACkB,gBAAA,CAAWC,OAAX,CAAmBd,iBAAA,CAAY2B,cAA/B,EAA+CC,eAAA,CAAUC,aAAzD,CAAD,CAAX;IACD;EACF,CAjDH;AAmDD"}
|
package/build/v1/search.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Auth } from '@verdaccio/auth';
|
|
2
2
|
import { Storage } from '@verdaccio/store';
|
|
3
3
|
/**
|
|
4
4
|
* Endpoint for npm search v1
|
|
@@ -6,4 +6,4 @@ import { Storage } from '@verdaccio/store';
|
|
|
6
6
|
* - {"objects":[],"total":0,"time":"Sun Jul 25 2021 14:09:11 GMT+0000 (Coordinated Universal Time)"}
|
|
7
7
|
* req: 'GET /-/v1/search?text=react&size=20&frpom=0&quality=0.65&popularity=0.98&maintenance=0.5'
|
|
8
8
|
*/
|
|
9
|
-
export default function (route: any, auth:
|
|
9
|
+
export default function (route: any, auth: Auth, storage: Storage): void;
|
package/build/v1/search.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","names":["debug","buildDebug","route","auth","storage","checkAccess","pkg","remoteUser","Promise","resolve","reject","allow_access","packageName","package","name","err","allowed","status","String","match","get","req","res","next","query","url","size","from","map","k","data","abort","AbortController","on","parseInt","search","checkAccessPromises","all","pkgItem","remote_user","final","filter","i","_","isNull","slice","logger","length","response","objects","total","time","Date","toUTCString","HTTP_STATUS","OK","json","error"],"sources":["../../src/v1/search.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport _ from 'lodash';\n\nimport {
|
|
1
|
+
{"version":3,"file":"search.js","names":["debug","buildDebug","route","auth","storage","checkAccess","pkg","remoteUser","Promise","resolve","reject","allow_access","packageName","package","name","err","allowed","status","String","match","get","req","res","next","query","url","size","from","map","k","data","abort","AbortController","on","parseInt","search","checkAccessPromises","all","pkgItem","remote_user","final","filter","i","_","isNull","slice","logger","length","response","objects","total","time","Date","toUTCString","HTTP_STATUS","OK","json","error"],"sources":["../../src/v1/search.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport _ from 'lodash';\n\nimport { Auth } from '@verdaccio/auth';\nimport { HTTP_STATUS, searchUtils } from '@verdaccio/core';\nimport { logger } from '@verdaccio/logger';\nimport { Storage } from '@verdaccio/store';\nimport { Manifest } from '@verdaccio/types';\n\nconst debug = buildDebug('verdaccio:api:search');\n\n/**\n * Endpoint for npm search v1\n * Empty value\n * - {\"objects\":[],\"total\":0,\"time\":\"Sun Jul 25 2021 14:09:11 GMT+0000 (Coordinated Universal Time)\"}\n * req: 'GET /-/v1/search?text=react&size=20&frpom=0&quality=0.65&popularity=0.98&maintenance=0.5'\n */\nexport default function (route, auth: Auth, storage: Storage): void {\n function 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\n route.get('/-/v1/search', async (req, res, next) => {\n const { query, url } = req;\n let [size, from] = ['size', 'from'].map((k) => query[k]);\n let data;\n const abort = new AbortController();\n\n req.on('aborted', () => {\n abort.abort();\n });\n\n size = parseInt(size, 10) || 20;\n from = parseInt(from, 10) || 0;\n\n try {\n data = await storage.search({\n query,\n url,\n abort,\n });\n debug('stream finish');\n const checkAccessPromises: searchUtils.SearchItemPkg[] = await Promise.all(\n data.map((pkgItem) => {\n return checkAccess(pkgItem, auth, req.remote_user);\n })\n );\n\n const final: searchUtils.SearchItemPkg[] = checkAccessPromises\n .filter((i) => !_.isNull(i))\n .slice(from, size);\n logger.debug(`search results ${final?.length}`);\n\n const response: searchUtils.SearchResults = {\n objects: final,\n total: final.length,\n time: new Date().toUTCString(),\n };\n\n res.status(HTTP_STATUS.OK).json(response);\n } catch (error) {\n logger.error({ error }, 'search endpoint has failed @{error.message}');\n next(next);\n return;\n }\n });\n}\n"],"mappings":"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"}
|
package/build/v1/token.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
|
-
import {
|
|
2
|
+
import { Auth } from '@verdaccio/auth';
|
|
3
3
|
import { Storage } from '@verdaccio/store';
|
|
4
4
|
import { Config, Token } from '@verdaccio/types';
|
|
5
5
|
export declare type NormalizeToken = Token & {
|
|
6
6
|
created: string;
|
|
7
7
|
};
|
|
8
|
-
export default function (route: Router, auth:
|
|
8
|
+
export default function (route: Router, auth: Auth, storage: Storage, config: Config): void;
|
package/build/v1/token.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.js","names":["normalizeToken","token","created","Date","toISOString","route","auth","storage","config","get","req","res","next","name","remote_user","_","isNil","tokens","readTokens","user","totalTokens","length","logger","debug","status","HTTP_STATUS","OK","objects","map","urls","error","msg","errorUtils","getCode","INTERNAL_ERROR","message","getUnauthorized","post","password","readonly","cidr_whitelist","body","isBoolean","isArray","BAD_DATA","SUPPORT_ERRORS","PARAMETERS_NOT_VALID","authenticate","err","errorCode","UNAUTHORIZED","isFunction","saveToken","NOT_IMPLEMENTED","STORAGE_NOT_IMPLEMENT","getApiToken","getInternalError","key","stringToMD5","maskedToken","mask","getTime","cidr","delete","params","tokenKey","deleteToken","info"],"sources":["../../src/v1/token.ts"],"sourcesContent":["import { Response, Router } from 'express';\nimport _ from 'lodash';\n\nimport { getApiToken } from '@verdaccio/auth';\nimport {
|
|
1
|
+
{"version":3,"file":"token.js","names":["normalizeToken","token","created","Date","toISOString","route","auth","storage","config","get","req","res","next","name","remote_user","_","isNil","tokens","readTokens","user","totalTokens","length","logger","debug","status","HTTP_STATUS","OK","objects","map","urls","error","msg","errorUtils","getCode","INTERNAL_ERROR","message","getUnauthorized","post","password","readonly","cidr_whitelist","body","isBoolean","isArray","BAD_DATA","SUPPORT_ERRORS","PARAMETERS_NOT_VALID","authenticate","err","errorCode","UNAUTHORIZED","isFunction","saveToken","NOT_IMPLEMENTED","STORAGE_NOT_IMPLEMENT","getApiToken","getInternalError","key","stringToMD5","maskedToken","mask","getTime","cidr","delete","params","tokenKey","deleteToken","info"],"sources":["../../src/v1/token.ts"],"sourcesContent":["import { Response, Router } from 'express';\nimport _ from 'lodash';\n\nimport { getApiToken } from '@verdaccio/auth';\nimport { Auth } from '@verdaccio/auth';\nimport { HTTP_STATUS, SUPPORT_ERRORS, errorUtils } from '@verdaccio/core';\nimport { logger } from '@verdaccio/logger';\nimport { Storage } from '@verdaccio/store';\nimport { Config, RemoteUser, Token } from '@verdaccio/types';\nimport { mask, stringToMD5 } from '@verdaccio/utils';\n\nimport { $NextFunctionVer, $RequestExtend } from '../../types/custom';\n\nexport type NormalizeToken = Token & {\n created: string;\n};\n\nfunction normalizeToken(token: Token): NormalizeToken {\n return {\n ...token,\n created: new Date(token.created).toISOString(),\n };\n}\n\n// https://github.com/npm/npm-profile/blob/latest/lib/index.js\nexport default function (route: Router, auth: Auth, storage: Storage, config: Config): void {\n route.get(\n '/-/npm/v1/tokens',\n async function (req: $RequestExtend, res: Response, next: $NextFunctionVer) {\n const { name } = req.remote_user;\n\n if (_.isNil(name) === false) {\n try {\n const tokens = await storage.readTokens({ user: name });\n const totalTokens = tokens.length;\n logger.debug({ totalTokens }, 'token list retrieved: @{totalTokens}');\n\n res.status(HTTP_STATUS.OK);\n return next({\n objects: tokens.map(normalizeToken),\n urls: {\n next: '', // TODO: pagination?\n },\n });\n } catch (error: any) {\n logger.error({ error: error.msg }, 'token list has failed: @{error}');\n return next(errorUtils.getCode(HTTP_STATUS.INTERNAL_ERROR, error.message));\n }\n }\n return next(errorUtils.getUnauthorized());\n }\n );\n\n route.post(\n '/-/npm/v1/tokens',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer) {\n const { password, readonly, cidr_whitelist } = req.body;\n const { name } = req.remote_user;\n\n if (!_.isBoolean(readonly) || !_.isArray(cidr_whitelist)) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_DATA, SUPPORT_ERRORS.PARAMETERS_NOT_VALID));\n }\n\n auth.authenticate(name, password, async (err, user?: RemoteUser) => {\n if (err) {\n const errorCode = err.message ? HTTP_STATUS.UNAUTHORIZED : HTTP_STATUS.INTERNAL_ERROR;\n return next(errorUtils.getCode(errorCode, err.message));\n }\n\n req.remote_user = user;\n\n if (!_.isFunction(storage.saveToken)) {\n return next(\n errorUtils.getCode(HTTP_STATUS.NOT_IMPLEMENTED, SUPPORT_ERRORS.STORAGE_NOT_IMPLEMENT)\n );\n }\n\n try {\n const token = await getApiToken(auth, config, user as RemoteUser, password);\n if (!token) {\n throw errorUtils.getInternalError();\n }\n\n const key = stringToMD5(token);\n // TODO: use a utility here\n const maskedToken = mask(token, 5);\n const created = new Date().getTime();\n\n /**\n * cidr_whitelist: is not being used, we pass it through\n * token: we do not store the real token (it is generated once and retrieved\n * to the user), just a mask of it.\n */\n const saveToken: Token = {\n user: name,\n token: maskedToken,\n key,\n cidr: cidr_whitelist,\n readonly,\n created,\n };\n\n await storage.saveToken(saveToken);\n logger.debug({ key, name }, 'token @{key} was created for user @{name}');\n return next(\n normalizeToken({\n token,\n user: name,\n key: saveToken.key,\n cidr: cidr_whitelist,\n readonly,\n created: saveToken.created,\n })\n );\n } catch (error: any) {\n logger.error({ error: error.msg }, 'token creation has failed: @{error}');\n return next(errorUtils.getInternalError(error.message));\n }\n });\n }\n );\n\n route.delete(\n '/-/npm/v1/tokens/token/:tokenKey',\n async (req: $RequestExtend, res: Response, next: $NextFunctionVer) => {\n const {\n params: { tokenKey },\n } = req;\n const { name } = req.remote_user;\n\n if (_.isNil(name) === false) {\n logger.debug({ name }, '@{name} has requested remove a token');\n try {\n await storage.deleteToken(name, tokenKey);\n logger.info({ tokenKey, name }, 'token id @{tokenKey} was revoked for user @{name}');\n return next({});\n } catch (error: any) {\n logger.error({ error: error.msg }, 'token creation has failed: @{error}');\n return next(errorUtils.getCode(HTTP_STATUS.INTERNAL_ERROR, error.message));\n }\n }\n return next(errorUtils.getUnauthorized());\n }\n );\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/api",
|
|
3
|
-
"version": "6.0.0-6-next.
|
|
3
|
+
"version": "6.0.0-6-next.32",
|
|
4
4
|
"description": "loaders logic",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -30,13 +30,13 @@
|
|
|
30
30
|
},
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@verdaccio/auth": "6.0.0-6-next.
|
|
34
|
-
"@verdaccio/config": "6.0.0-6-next.
|
|
35
|
-
"@verdaccio/core": "6.0.0-6-next.
|
|
36
|
-
"@verdaccio/logger": "6.0.0-6-next.
|
|
37
|
-
"@verdaccio/middleware": "6.0.0-6-next.
|
|
38
|
-
"@verdaccio/store": "6.0.0-6-next.
|
|
39
|
-
"@verdaccio/utils": "6.0.0-6-next.
|
|
33
|
+
"@verdaccio/auth": "6.0.0-6-next.28",
|
|
34
|
+
"@verdaccio/config": "6.0.0-6-next.49",
|
|
35
|
+
"@verdaccio/core": "6.0.0-6-next.49",
|
|
36
|
+
"@verdaccio/logger": "6.0.0-6-next.17",
|
|
37
|
+
"@verdaccio/middleware": "6.0.0-6-next.28",
|
|
38
|
+
"@verdaccio/store": "6.0.0-6-next.29",
|
|
39
|
+
"@verdaccio/utils": "6.0.0-6-next.17",
|
|
40
40
|
"abortcontroller-polyfill": "1.7.3",
|
|
41
41
|
"cookies": "0.8.0",
|
|
42
42
|
"debug": "4.3.4",
|
|
@@ -47,10 +47,10 @@
|
|
|
47
47
|
"semver": "7.3.7"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@types/node": "16.11.
|
|
51
|
-
"@verdaccio/server": "6.0.0-6-next.
|
|
52
|
-
"@verdaccio/types": "11.0.0-6-next.
|
|
53
|
-
"@verdaccio/test-helper": "
|
|
50
|
+
"@types/node": "16.11.62",
|
|
51
|
+
"@verdaccio/server": "6.0.0-6-next.38",
|
|
52
|
+
"@verdaccio/types": "11.0.0-6-next.17",
|
|
53
|
+
"@verdaccio/test-helper": "2.0.0-6-next.6",
|
|
54
54
|
"supertest": "6.2.4",
|
|
55
55
|
"nock": "13.2.9",
|
|
56
56
|
"mockdate": "3.0.5"
|
package/src/dist-tags.ts
CHANGED
|
@@ -2,14 +2,14 @@ import { Router } from 'express';
|
|
|
2
2
|
import _ from 'lodash';
|
|
3
3
|
import mime from 'mime';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Auth } from '@verdaccio/auth';
|
|
6
6
|
import { constants, errorUtils } from '@verdaccio/core';
|
|
7
7
|
import { allow, media } from '@verdaccio/middleware';
|
|
8
8
|
import { Storage } from '@verdaccio/store';
|
|
9
9
|
|
|
10
10
|
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';
|
|
11
11
|
|
|
12
|
-
export default function (route: Router, auth:
|
|
12
|
+
export default function (route: Router, auth: Auth, storage: Storage): void {
|
|
13
13
|
const can = allow(auth);
|
|
14
14
|
const addTagPackageVersionMiddleware = async function (
|
|
15
15
|
req: $RequestExtend,
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import bodyParser from 'body-parser';
|
|
2
2
|
import express, { Router } from 'express';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { Auth } from '@verdaccio/auth';
|
|
5
5
|
import {
|
|
6
6
|
antiLoop,
|
|
7
7
|
encodeScopePackage,
|
|
@@ -24,7 +24,7 @@ import v1Search from './v1/search';
|
|
|
24
24
|
import token from './v1/token';
|
|
25
25
|
import whoami from './whoami';
|
|
26
26
|
|
|
27
|
-
export default function (config: Config, auth:
|
|
27
|
+
export default function (config: Config, auth: Auth, storage: Storage): Router {
|
|
28
28
|
/* eslint new-cap:off */
|
|
29
29
|
const app = express.Router();
|
|
30
30
|
/* eslint new-cap:off */
|
|
@@ -52,7 +52,7 @@ export default function (config: Config, auth: IAuth, storage: Storage): Router
|
|
|
52
52
|
// for "npm whoami"
|
|
53
53
|
whoami(app);
|
|
54
54
|
pkg(app, auth, storage);
|
|
55
|
-
profile(app, auth);
|
|
55
|
+
profile(app, auth, config);
|
|
56
56
|
// @deprecated endpoint, 404 by default
|
|
57
57
|
search(app);
|
|
58
58
|
user(app, auth, config);
|
package/src/package.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import buildDebug from 'debug';
|
|
2
2
|
import { Router } from 'express';
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import { HEADERS, HEADER_TYPE } from '@verdaccio/core';
|
|
4
|
+
import { Auth } from '@verdaccio/auth';
|
|
5
|
+
import { HEADERS, HEADER_TYPE, stringUtils } from '@verdaccio/core';
|
|
6
6
|
import { allow } from '@verdaccio/middleware';
|
|
7
7
|
import { Storage } from '@verdaccio/store';
|
|
8
8
|
|
|
@@ -10,7 +10,7 @@ import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/cust
|
|
|
10
10
|
|
|
11
11
|
const debug = buildDebug('verdaccio:api:package');
|
|
12
12
|
|
|
13
|
-
export default function (route: Router, auth:
|
|
13
|
+
export default function (route: Router, auth: Auth, storage: Storage): void {
|
|
14
14
|
const can = allow(auth);
|
|
15
15
|
|
|
16
16
|
route.get(
|
|
@@ -25,7 +25,8 @@ export default function (route: Router, auth: IAuth, storage: Storage): void {
|
|
|
25
25
|
const name = req.params.package;
|
|
26
26
|
let version = req.params.version;
|
|
27
27
|
const write = req.query.write === 'true';
|
|
28
|
-
const abbreviated =
|
|
28
|
+
const abbreviated =
|
|
29
|
+
stringUtils.getByQualityPriorityValue(req.get('Accept')) === Storage.ABBREVIATED_HEADER;
|
|
29
30
|
const requestOptions = {
|
|
30
31
|
protocol: req.protocol,
|
|
31
32
|
headers: req.headers as any,
|
|
@@ -43,6 +44,12 @@ export default function (route: Router, auth: IAuth, storage: Storage): void {
|
|
|
43
44
|
version,
|
|
44
45
|
requestOptions,
|
|
45
46
|
});
|
|
47
|
+
if (abbreviated) {
|
|
48
|
+
_res.setHeader(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_INSTALL_CHARSET);
|
|
49
|
+
} else {
|
|
50
|
+
_res.setHeader(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON);
|
|
51
|
+
}
|
|
52
|
+
|
|
46
53
|
next(manifest);
|
|
47
54
|
} catch (err) {
|
|
48
55
|
next(err);
|
package/src/publish.ts
CHANGED
|
@@ -2,7 +2,7 @@ import buildDebug from 'debug';
|
|
|
2
2
|
import { Router } from 'express';
|
|
3
3
|
import mime from 'mime';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Auth } from '@verdaccio/auth';
|
|
6
6
|
import { API_MESSAGE, HTTP_STATUS } from '@verdaccio/core';
|
|
7
7
|
import { logger } from '@verdaccio/logger';
|
|
8
8
|
import { allow, expectJson, media } from '@verdaccio/middleware';
|
|
@@ -11,7 +11,6 @@ import { Storage } from '@verdaccio/store';
|
|
|
11
11
|
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';
|
|
12
12
|
|
|
13
13
|
// import star from './star';
|
|
14
|
-
// import { isPublishablePackage, isRelatedToDeprecation } from './utils';
|
|
15
14
|
|
|
16
15
|
const debug = buildDebug('verdaccio:api:publish');
|
|
17
16
|
|
|
@@ -93,24 +92,22 @@ const debug = buildDebug('verdaccio:api:publish');
|
|
|
93
92
|
}
|
|
94
93
|
*
|
|
95
94
|
*/
|
|
96
|
-
export default function publish(router: Router, auth:
|
|
95
|
+
export default function publish(router: Router, auth: Auth, storage: Storage): void {
|
|
97
96
|
const can = allow(auth);
|
|
98
|
-
// publish (update manifest) v6
|
|
99
97
|
router.put(
|
|
100
98
|
'/:package',
|
|
101
99
|
can('publish'),
|
|
102
100
|
media(mime.getType('json')),
|
|
103
101
|
expectJson,
|
|
104
|
-
|
|
102
|
+
publishPackage(storage)
|
|
105
103
|
);
|
|
106
104
|
|
|
107
|
-
// unpublish a pacakge v6
|
|
108
105
|
router.put(
|
|
109
106
|
'/:package/-rev/:revision',
|
|
110
107
|
can('unpublish'),
|
|
111
108
|
media(mime.getType('json')),
|
|
112
109
|
expectJson,
|
|
113
|
-
|
|
110
|
+
publishPackage(storage)
|
|
114
111
|
);
|
|
115
112
|
|
|
116
113
|
/**
|
|
@@ -121,7 +118,6 @@ export default function publish(router: Router, auth: IAuth, storage: Storage):
|
|
|
121
118
|
* npm http fetch GET 304 http://localhost:4873/package-name?write=true 1076ms (from cache)
|
|
122
119
|
* npm http fetch DELETE 201 http://localhost:4873/package-name/-rev/18-d8ebe3020bd4ac9c 22ms
|
|
123
120
|
*/
|
|
124
|
-
// v6
|
|
125
121
|
router.delete(
|
|
126
122
|
'/:package/-rev/:revision',
|
|
127
123
|
can('unpublish'),
|
|
@@ -177,20 +173,20 @@ export default function publish(router: Router, auth: IAuth, storage: Storage):
|
|
|
177
173
|
);
|
|
178
174
|
}
|
|
179
175
|
|
|
180
|
-
export function
|
|
176
|
+
export function publishPackage(storage: Storage): any {
|
|
181
177
|
return async function (
|
|
182
178
|
req: $RequestExtend,
|
|
183
|
-
|
|
179
|
+
res: $ResponseExtend,
|
|
184
180
|
next: $NextFunctionVer
|
|
185
181
|
): Promise<void> {
|
|
186
182
|
const ac = new AbortController();
|
|
187
183
|
const packageName = req.params.package;
|
|
188
184
|
const { revision } = req.params;
|
|
189
185
|
const metadata = req.body;
|
|
186
|
+
const username = req?.remote_user?.name;
|
|
190
187
|
|
|
191
188
|
try {
|
|
192
|
-
|
|
193
|
-
await storage.updateManifest(metadata, {
|
|
189
|
+
const message = await storage.updateManifest(metadata, {
|
|
194
190
|
name: packageName,
|
|
195
191
|
revision,
|
|
196
192
|
signal: ac.signal,
|
|
@@ -199,16 +195,15 @@ export function publishPackageNext(storage: Storage): any {
|
|
|
199
195
|
protocol: req.protocol,
|
|
200
196
|
// @ts-ignore
|
|
201
197
|
headers: req.headers,
|
|
198
|
+
username,
|
|
202
199
|
},
|
|
203
200
|
});
|
|
204
|
-
|
|
201
|
+
|
|
202
|
+
res.status(HTTP_STATUS.CREATED);
|
|
205
203
|
|
|
206
204
|
return next({
|
|
207
|
-
// TODO: this could be also Package Updated based on the
|
|
208
|
-
// action, deprecate, star, publish new version, or create a package
|
|
209
|
-
// the message some return from the method
|
|
210
|
-
ok: API_MESSAGE.PKG_CREATED,
|
|
211
205
|
success: true,
|
|
206
|
+
ok: message,
|
|
212
207
|
});
|
|
213
208
|
} catch (err: any) {
|
|
214
209
|
// TODO: review if we need the abort controller here
|
package/src/user.ts
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import buildDebug from 'debug';
|
|
2
2
|
import { Response, Router } from 'express';
|
|
3
|
-
import _ from 'lodash';
|
|
4
3
|
|
|
5
4
|
import { getApiToken } from '@verdaccio/auth';
|
|
6
|
-
import {
|
|
5
|
+
import { Auth } from '@verdaccio/auth';
|
|
7
6
|
import { createRemoteUser } from '@verdaccio/config';
|
|
8
|
-
import { API_ERROR, API_MESSAGE, HTTP_STATUS, errorUtils } from '@verdaccio/core';
|
|
7
|
+
import { API_ERROR, API_MESSAGE, HTTP_STATUS, errorUtils, validatioUtils } from '@verdaccio/core';
|
|
9
8
|
import { logger } from '@verdaccio/logger';
|
|
10
9
|
import { Config, RemoteUser } from '@verdaccio/types';
|
|
11
|
-
import { getAuthenticatedMessage, mask
|
|
10
|
+
import { getAuthenticatedMessage, mask } from '@verdaccio/utils';
|
|
12
11
|
|
|
13
12
|
import { $NextFunctionVer, $RequestExtend } from '../types/custom';
|
|
14
13
|
|
|
15
14
|
const debug = buildDebug('verdaccio:api:user');
|
|
16
15
|
|
|
17
|
-
export default function (route: Router, auth:
|
|
16
|
+
export default function (route: Router, auth: Auth, config: Config): void {
|
|
18
17
|
route.get(
|
|
19
18
|
'/-/user/:org_couchdb_user',
|
|
20
19
|
function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
|
|
@@ -42,7 +41,7 @@ export default function (route: Router, auth: IAuth, config: Config): void {
|
|
|
42
41
|
*
|
|
43
42
|
* @export
|
|
44
43
|
* @param {Router} route
|
|
45
|
-
* @param {
|
|
44
|
+
* @param {Auth} auth
|
|
46
45
|
* @param {Config} config
|
|
47
46
|
*/
|
|
48
47
|
route.put(
|
|
@@ -50,9 +49,9 @@ export default function (route: Router, auth: IAuth, config: Config): void {
|
|
|
50
49
|
function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
|
|
51
50
|
const { name, password } = req.body;
|
|
52
51
|
debug('login or adduser');
|
|
53
|
-
const remoteName = req
|
|
52
|
+
const remoteName = req?.remote_user?.name;
|
|
54
53
|
|
|
55
|
-
if (
|
|
54
|
+
if (typeof remoteName !== 'undefined' && typeof name === 'string' && remoteName === name) {
|
|
56
55
|
debug('login: no remote user detected');
|
|
57
56
|
auth.authenticate(
|
|
58
57
|
name,
|
|
@@ -68,7 +67,7 @@ export default function (route: Router, auth: IAuth, config: Config): void {
|
|
|
68
67
|
);
|
|
69
68
|
}
|
|
70
69
|
|
|
71
|
-
const restoredRemoteUser: RemoteUser = createRemoteUser(name, user
|
|
70
|
+
const restoredRemoteUser: RemoteUser = createRemoteUser(name, user?.groups || []);
|
|
72
71
|
const token = await getApiToken(auth, config, restoredRemoteUser, password);
|
|
73
72
|
debug('login: new token');
|
|
74
73
|
if (!token) {
|
|
@@ -87,10 +86,15 @@ export default function (route: Router, auth: IAuth, config: Config): void {
|
|
|
87
86
|
}
|
|
88
87
|
);
|
|
89
88
|
} else {
|
|
90
|
-
if (
|
|
89
|
+
if (
|
|
90
|
+
validatioUtils.validatePassword(
|
|
91
|
+
password,
|
|
92
|
+
config?.serverSettings?.passwordValidationRegex
|
|
93
|
+
) === false
|
|
94
|
+
) {
|
|
91
95
|
debug('adduser: invalid password');
|
|
92
96
|
// eslint-disable-next-line new-cap
|
|
93
|
-
return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.PASSWORD_SHORT
|
|
97
|
+
return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.PASSWORD_SHORT));
|
|
94
98
|
}
|
|
95
99
|
|
|
96
100
|
auth.add_user(name, password, async function (err, user): Promise<void> {
|
|
@@ -108,8 +112,12 @@ export default function (route: Router, auth: IAuth, config: Config): void {
|
|
|
108
112
|
}
|
|
109
113
|
|
|
110
114
|
const token =
|
|
111
|
-
name && password
|
|
112
|
-
|
|
115
|
+
name && password
|
|
116
|
+
? await getApiToken(auth, config, user as RemoteUser, password)
|
|
117
|
+
: undefined;
|
|
118
|
+
if (token) {
|
|
119
|
+
debug('adduser: new token %o', mask(token as string, 4));
|
|
120
|
+
}
|
|
113
121
|
if (!token) {
|
|
114
122
|
return next(errorUtils.getUnauthorized());
|
|
115
123
|
}
|
package/src/v1/profile.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { Response, Router } from 'express';
|
|
2
2
|
import _ from 'lodash';
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
4
|
+
import { Auth } from '@verdaccio/auth';
|
|
5
|
+
import {
|
|
6
|
+
API_ERROR,
|
|
7
|
+
APP_ERROR,
|
|
8
|
+
HTTP_STATUS,
|
|
9
|
+
SUPPORT_ERRORS,
|
|
10
|
+
errorUtils,
|
|
11
|
+
validatioUtils,
|
|
12
|
+
} from '@verdaccio/core';
|
|
13
|
+
import { Config } from '@verdaccio/types';
|
|
7
14
|
|
|
8
15
|
import { $NextFunctionVer, $RequestExtend } from '../../types/custom';
|
|
9
16
|
|
|
@@ -18,7 +25,7 @@ export interface Profile {
|
|
|
18
25
|
fullname: string;
|
|
19
26
|
}
|
|
20
27
|
|
|
21
|
-
export default function (route: Router, auth:
|
|
28
|
+
export default function (route: Router, auth: Auth, config: Config): void {
|
|
22
29
|
function buildProfile(name: string): Profile {
|
|
23
30
|
return {
|
|
24
31
|
tfa: false,
|
|
@@ -60,9 +67,14 @@ export default function (route: Router, auth: IAuth): void {
|
|
|
60
67
|
const { name } = req.remote_user;
|
|
61
68
|
|
|
62
69
|
if (_.isNil(password) === false) {
|
|
63
|
-
if (
|
|
70
|
+
if (
|
|
71
|
+
validatioUtils.validatePassword(
|
|
72
|
+
password.new,
|
|
73
|
+
config?.serverSettings?.passwordValidationRegex
|
|
74
|
+
) === false
|
|
75
|
+
) {
|
|
64
76
|
/* eslint new-cap:off */
|
|
65
|
-
return next(errorUtils.getCode(HTTP_STATUS.UNAUTHORIZED, API_ERROR.PASSWORD_SHORT
|
|
77
|
+
return next(errorUtils.getCode(HTTP_STATUS.UNAUTHORIZED, API_ERROR.PASSWORD_SHORT));
|
|
66
78
|
/* eslint new-cap:off */
|
|
67
79
|
}
|
|
68
80
|
|
package/src/v1/search.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import buildDebug from 'debug';
|
|
2
2
|
import _ from 'lodash';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { Auth } from '@verdaccio/auth';
|
|
5
5
|
import { HTTP_STATUS, searchUtils } from '@verdaccio/core';
|
|
6
6
|
import { logger } from '@verdaccio/logger';
|
|
7
7
|
import { Storage } from '@verdaccio/store';
|
|
@@ -15,7 +15,7 @@ const debug = buildDebug('verdaccio:api:search');
|
|
|
15
15
|
* - {"objects":[],"total":0,"time":"Sun Jul 25 2021 14:09:11 GMT+0000 (Coordinated Universal Time)"}
|
|
16
16
|
* req: 'GET /-/v1/search?text=react&size=20&frpom=0&quality=0.65&popularity=0.98&maintenance=0.5'
|
|
17
17
|
*/
|
|
18
|
-
export default function (route, auth:
|
|
18
|
+
export default function (route, auth: Auth, storage: Storage): void {
|
|
19
19
|
function checkAccess(pkg: any, auth: any, remoteUser): Promise<Manifest | null> {
|
|
20
20
|
return new Promise((resolve, reject) => {
|
|
21
21
|
auth.allow_access({ packageName: pkg?.package?.name }, remoteUser, function (err, allowed) {
|
package/src/v1/token.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Response, Router } from 'express';
|
|
|
2
2
|
import _ from 'lodash';
|
|
3
3
|
|
|
4
4
|
import { getApiToken } from '@verdaccio/auth';
|
|
5
|
-
import {
|
|
5
|
+
import { Auth } from '@verdaccio/auth';
|
|
6
6
|
import { HTTP_STATUS, SUPPORT_ERRORS, errorUtils } from '@verdaccio/core';
|
|
7
7
|
import { logger } from '@verdaccio/logger';
|
|
8
8
|
import { Storage } from '@verdaccio/store';
|
|
@@ -23,7 +23,7 @@ function normalizeToken(token: Token): NormalizeToken {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
// https://github.com/npm/npm-profile/blob/latest/lib/index.js
|
|
26
|
-
export default function (route: Router, auth:
|
|
26
|
+
export default function (route: Router, auth: Auth, storage: Storage, config: Config): void {
|
|
27
27
|
route.get(
|
|
28
28
|
'/-/npm/v1/tokens',
|
|
29
29
|
async function (req: $RequestExtend, res: Response, next: $NextFunctionVer) {
|
|
@@ -61,7 +61,7 @@ export default function (route: Router, auth: IAuth, storage: Storage, config: C
|
|
|
61
61
|
return next(errorUtils.getCode(HTTP_STATUS.BAD_DATA, SUPPORT_ERRORS.PARAMETERS_NOT_VALID));
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
auth.authenticate(name, password, async (err, user
|
|
64
|
+
auth.authenticate(name, password, async (err, user?: RemoteUser) => {
|
|
65
65
|
if (err) {
|
|
66
66
|
const errorCode = err.message ? HTTP_STATUS.UNAUTHORIZED : HTTP_STATUS.INTERNAL_ERROR;
|
|
67
67
|
return next(errorUtils.getCode(errorCode, err.message));
|
|
@@ -76,7 +76,7 @@ export default function (route: Router, auth: IAuth, storage: Storage, config: C
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
try {
|
|
79
|
-
const token = await getApiToken(auth, config, user, password);
|
|
79
|
+
const token = await getApiToken(auth, config, user as RemoteUser, password);
|
|
80
80
|
if (!token) {
|
|
81
81
|
throw errorUtils.getInternalError();
|
|
82
82
|
}
|
|
@@ -27,7 +27,8 @@ export const getConf = (conf) => {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
export async function initializeServer(configName): Promise<Application> {
|
|
30
|
-
|
|
30
|
+
const config = getConf(configName);
|
|
31
|
+
return initializeServerHelper(config, [apiMiddleware], Storage);
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
export function createUser(app, name: string, password: string): supertest.Test {
|
|
@@ -90,7 +90,7 @@ describe('package', () => {
|
|
|
90
90
|
.get(`/${pkg}`)
|
|
91
91
|
.set(HEADERS.ACCEPT, HEADERS.JSON)
|
|
92
92
|
.set(HEADERS.ACCEPT, Storage.ABBREVIATED_HEADER)
|
|
93
|
-
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.
|
|
93
|
+
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_INSTALL_CHARSET)
|
|
94
94
|
.expect(HTTP_STATUS.OK);
|
|
95
95
|
expect(response.body.name).toEqual(pkg);
|
|
96
96
|
expect(response.body.time).toBeDefined();
|
|
@@ -22,6 +22,9 @@ jest.mock('@verdaccio/auth', () => ({
|
|
|
22
22
|
apiJWTmiddleware() {
|
|
23
23
|
return mockApiJWTmiddleware();
|
|
24
24
|
}
|
|
25
|
+
init() {
|
|
26
|
+
return Promise.resolve();
|
|
27
|
+
}
|
|
25
28
|
allow_access(_d, f_, cb) {
|
|
26
29
|
cb(null, true);
|
|
27
30
|
}
|
|
@@ -157,13 +160,13 @@ describe('publish', () => {
|
|
|
157
160
|
decodeURIComponent(pkgName),
|
|
158
161
|
'1.0.1-patch'
|
|
159
162
|
).expect(HTTP_STATUS.CREATED);
|
|
160
|
-
expect(response.body.ok).toEqual(API_MESSAGE.
|
|
163
|
+
expect(response.body.ok).toEqual(API_MESSAGE.PKG_CHANGED);
|
|
161
164
|
const response2 = await publishVersion(
|
|
162
165
|
app,
|
|
163
166
|
decodeURIComponent(pkgName),
|
|
164
167
|
'1.0.2-patch'
|
|
165
168
|
).expect(HTTP_STATUS.CREATED);
|
|
166
|
-
expect(response2.body.ok).toEqual(API_MESSAGE.
|
|
169
|
+
expect(response2.body.ok).toEqual(API_MESSAGE.PKG_CHANGED);
|
|
167
170
|
}
|
|
168
171
|
);
|
|
169
172
|
});
|