@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.
@@ -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 { IAuth } from '@verdaccio/auth';\nimport { API_ERROR, APP_ERROR, HTTP_STATUS, SUPPORT_ERRORS, errorUtils } from '@verdaccio/core';\nimport { validatePassword } from '@verdaccio/utils';\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: IAuth): 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 (validatePassword(password.new) === false) {\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":"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"}
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":"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"}
@@ -1,4 +1,4 @@
1
- import { IAuth } from '@verdaccio/auth';
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: IAuth, storage: Storage): void;
9
+ export default function (route: any, auth: Auth, storage: Storage): void;
@@ -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 { IAuth } 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: IAuth, 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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"}
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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"}
@@ -1,8 +1,8 @@
1
1
  import { Router } from 'express';
2
- import { IAuth } from '@verdaccio/auth';
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: IAuth, storage: Storage, config: Config): void;
8
+ export default function (route: Router, auth: Auth, storage: Storage, config: Config): void;
@@ -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 { IAuth } 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: IAuth, 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, 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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"}
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.30",
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.26",
34
- "@verdaccio/config": "6.0.0-6-next.47",
35
- "@verdaccio/core": "6.0.0-6-next.47",
36
- "@verdaccio/logger": "6.0.0-6-next.15",
37
- "@verdaccio/middleware": "6.0.0-6-next.26",
38
- "@verdaccio/store": "6.0.0-6-next.27",
39
- "@verdaccio/utils": "6.0.0-6-next.15",
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.56",
51
- "@verdaccio/server": "6.0.0-6-next.36",
52
- "@verdaccio/types": "11.0.0-6-next.16",
53
- "@verdaccio/test-helper": "1.1.0-6-next.4",
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 { IAuth } from '@verdaccio/auth';
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: IAuth, storage: Storage): void {
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 { IAuth } from '@verdaccio/auth';
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: IAuth, storage: Storage): Router {
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 { IAuth } from '@verdaccio/auth';
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: IAuth, storage: Storage): void {
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 = req.get('Accept') === Storage.ABBREVIATED_HEADER;
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 { IAuth } from '@verdaccio/auth';
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: IAuth, storage: Storage): void {
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
- publishPackageNext(storage)
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
- publishPackageNext(storage)
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 publishPackageNext(storage: Storage): any {
176
+ export function publishPackage(storage: Storage): any {
181
177
  return async function (
182
178
  req: $RequestExtend,
183
- _res: $ResponseExtend,
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
- debug('publishing %s', packageName);
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
- _res.status(HTTP_STATUS.CREATED);
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 { IAuth } from '@verdaccio/auth';
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, validatePassword } from '@verdaccio/utils';
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: IAuth, config: Config): void {
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 {IAuth} auth
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.remote_user.name;
52
+ const remoteName = req?.remote_user?.name;
54
53
 
55
- if (_.isNil(remoteName) === false && _.isNil(name) === false && remoteName === name) {
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.groups || []);
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 (validatePassword(password) === false) {
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 ? await getApiToken(auth, config, user, password) : undefined;
112
- debug('adduser: new token %o', mask(token as string, 4));
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 { IAuth } from '@verdaccio/auth';
5
- import { API_ERROR, APP_ERROR, HTTP_STATUS, SUPPORT_ERRORS, errorUtils } from '@verdaccio/core';
6
- import { validatePassword } from '@verdaccio/utils';
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: IAuth): void {
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 (validatePassword(password.new) === false) {
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 { IAuth } from '@verdaccio/auth';
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: IAuth, storage: Storage): void {
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 { IAuth } from '@verdaccio/auth';
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: IAuth, storage: Storage, config: Config): void {
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: RemoteUser) => {
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
- return initializeServerHelper(getConf(configName), [apiMiddleware], Storage);
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.JSON_CHARSET)
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.PKG_CREATED);
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.PKG_CREATED);
169
+ expect(response2.body.ok).toEqual(API_MESSAGE.PKG_CHANGED);
167
170
  }
168
171
  );
169
172
  });