@verdaccio/api 6.0.0-6-next.33 → 6.0.0-6-next.34
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 +26 -0
- package/build/dist-tags.js +0 -11
- package/build/dist-tags.js.map +1 -1
- package/build/stars.js +7 -3
- package/build/stars.js.map +1 -1
- package/build/user.js +2 -0
- package/build/user.js.map +1 -1
- package/build/v1/token.js +1 -0
- package/build/v1/token.js.map +1 -1
- package/package.json +9 -9
- package/src/dist-tags.ts +0 -20
- package/src/stars.ts +7 -5
- package/src/user.ts +10 -1
- package/src/v1/token.ts +2 -1
- package/test/integration/_helper.ts +42 -3
- package/test/integration/config/star.yaml +26 -0
- package/test/integration/publish.spec.ts +17 -48
- package/test/integration/star.spec.ts +73 -0
- package/types/custom.d.ts +1 -1
- package/build/star.d.ts +0 -4
- package/build/star.js +0 -90
- package/build/star.js.map +0 -1
- package/src/star.ts +0 -88
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @verdaccio/api
|
|
2
2
|
|
|
3
|
+
## 6.0.0-6-next.34
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 4b29d715: chore: move improvements from v5 to v6
|
|
8
|
+
|
|
9
|
+
Migrate improvements form v5 to v6:
|
|
10
|
+
|
|
11
|
+
- https://github.com/verdaccio/verdaccio/pull/3158
|
|
12
|
+
- https://github.com/verdaccio/verdaccio/pull/3151
|
|
13
|
+
- https://github.com/verdaccio/verdaccio/pull/2271
|
|
14
|
+
- https://github.com/verdaccio/verdaccio/pull/2787
|
|
15
|
+
- https://github.com/verdaccio/verdaccio/pull/2791
|
|
16
|
+
- https://github.com/verdaccio/verdaccio/pull/2205
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- Updated dependencies [4b29d715]
|
|
21
|
+
- @verdaccio/auth@6.0.0-6-next.30
|
|
22
|
+
- @verdaccio/config@6.0.0-6-next.51
|
|
23
|
+
- @verdaccio/core@6.0.0-6-next.51
|
|
24
|
+
- @verdaccio/middleware@6.0.0-6-next.30
|
|
25
|
+
- @verdaccio/store@6.0.0-6-next.31
|
|
26
|
+
- @verdaccio/logger@6.0.0-6-next.19
|
|
27
|
+
- @verdaccio/utils@6.0.0-6-next.19
|
|
28
|
+
|
|
3
29
|
## 6.0.0-6-next.33
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
package/build/dist-tags.js
CHANGED
|
@@ -75,16 +75,5 @@ function _default(route, auth, storage) {
|
|
|
75
75
|
next(err);
|
|
76
76
|
}
|
|
77
77
|
});
|
|
78
|
-
route.post('/-/package/:package/dist-tags', can('publish'), async function (req, res, next) {
|
|
79
|
-
try {
|
|
80
|
-
await storage.mergeTagsNext(req.params.package, req.body);
|
|
81
|
-
res.status(_core.constants.HTTP_STATUS.CREATED);
|
|
82
|
-
return next({
|
|
83
|
-
ok: _core.constants.API_MESSAGE.TAG_UPDATED
|
|
84
|
-
});
|
|
85
|
-
} catch (err) {
|
|
86
|
-
next(err);
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
78
|
}
|
|
90
79
|
//# sourceMappingURL=dist-tags.js.map
|
package/build/dist-tags.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dist-tags.js","names":["route","auth","storage","can","allow","addTagPackageVersionMiddleware","req","res","next","_","isString","body","errorUtils","getBadRequest","tags","params","tag","mergeTagsNext","package","status","constants","HTTP_STATUS","CREATED","ok","API_MESSAGE","TAG_ADDED","err","put","media","mime","getType","delete","TAG_REMOVED","get","name","requestOptions","protocol","headers","host","remoteAddress","socket","manifest","getPackageByOptions","uplinksLook","DIST_TAGS"
|
|
1
|
+
{"version":3,"file":"dist-tags.js","names":["route","auth","storage","can","allow","addTagPackageVersionMiddleware","req","res","next","_","isString","body","errorUtils","getBadRequest","tags","params","tag","mergeTagsNext","package","status","constants","HTTP_STATUS","CREATED","ok","API_MESSAGE","TAG_ADDED","err","put","media","mime","getType","delete","TAG_REMOVED","get","name","requestOptions","protocol","headers","host","remoteAddress","socket","manifest","getPackageByOptions","uplinksLook","DIST_TAGS"],"sources":["../src/dist-tags.ts"],"sourcesContent":["import { Router } from 'express';\nimport _ from 'lodash';\nimport mime from 'mime';\n\nimport { Auth } from '@verdaccio/auth';\nimport { constants, errorUtils } from '@verdaccio/core';\nimport { allow, media } from '@verdaccio/middleware';\nimport { Storage } from '@verdaccio/store';\n\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';\n\nexport default function (route: Router, auth: Auth, storage: Storage): void {\n const can = allow(auth);\n const addTagPackageVersionMiddleware = async function (\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n ): Promise<$NextFunctionVer> {\n if (_.isString(req.body) === false) {\n return next(errorUtils.getBadRequest('version is missing'));\n }\n\n const tags = {};\n tags[req.params.tag] = req.body;\n try {\n await storage.mergeTagsNext(req.params.package, tags);\n res.status(constants.HTTP_STATUS.CREATED);\n return next({\n ok: constants.API_MESSAGE.TAG_ADDED,\n });\n } catch (err) {\n next(err);\n }\n };\n\n // tagging a package.\n route.put(\n '/:package/:tag',\n can('publish'),\n media(mime.getType('json')),\n addTagPackageVersionMiddleware\n );\n\n route.put(\n '/-/package/:package/dist-tags/:tag',\n can('publish'),\n media(mime.getType('json')),\n addTagPackageVersionMiddleware\n );\n\n route.delete(\n '/-/package/:package/dist-tags/:tag',\n can('publish'),\n async function (\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n ): Promise<void> {\n const tags = {};\n tags[req.params.tag] = null;\n try {\n await storage.mergeTagsNext(req.params.package, tags);\n res.status(constants.HTTP_STATUS.CREATED);\n return next({\n ok: constants.API_MESSAGE.TAG_REMOVED,\n });\n } catch (err) {\n next(err);\n }\n }\n );\n\n route.get(\n '/-/package/:package/dist-tags',\n can('access'),\n async function (\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n ): Promise<void> {\n const name = req.params.package;\n const requestOptions = {\n protocol: req.protocol,\n headers: req.headers as any,\n // FIXME: if we migrate to req.hostname, the port is not longer included.\n host: req.host,\n remoteAddress: req.socket.remoteAddress,\n };\n try {\n const manifest = await storage.getPackageByOptions({\n name,\n uplinksLook: true,\n requestOptions,\n });\n next(manifest[constants.DIST_TAGS]);\n } catch (err) {\n next(err);\n }\n }\n );\n}\n"],"mappings":"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"}
|
package/build/stars.js
CHANGED
|
@@ -13,11 +13,15 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
13
13
|
|
|
14
14
|
function _default(route, storage) {
|
|
15
15
|
route.get('/-/_view/starredByUser', async (req, res, next) => {
|
|
16
|
-
const
|
|
16
|
+
const query = req.query;
|
|
17
|
+
|
|
18
|
+
if (typeof (query === null || query === void 0 ? void 0 : query.key) !== 'string') {
|
|
19
|
+
return next(_core.errorUtils.getBadRequest('missing query key username'));
|
|
20
|
+
}
|
|
17
21
|
|
|
18
22
|
try {
|
|
19
|
-
const localPackages = await storage.
|
|
20
|
-
const filteredPackages = localPackages.filter(localPackage => _lodash.default.keys(localPackage[_core.USERS]).includes(
|
|
23
|
+
const localPackages = await storage.getLocalDatabase();
|
|
24
|
+
const filteredPackages = localPackages.filter(localPackage => _lodash.default.keys(localPackage[_core.USERS]).includes(query === null || query === void 0 ? void 0 : query.key.toString().replace(/['"]+/g, '')));
|
|
21
25
|
res.status(_core.HTTP_STATUS.OK);
|
|
22
26
|
next({
|
|
23
27
|
rows: filteredPackages.map(filteredPackage => ({
|
package/build/stars.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stars.js","names":["route","storage","get","req","res","next","
|
|
1
|
+
{"version":3,"file":"stars.js","names":["route","storage","get","req","res","next","query","key","errorUtils","getBadRequest","localPackages","getLocalDatabase","filteredPackages","filter","localPackage","_","keys","USERS","includes","toString","replace","status","HTTP_STATUS","OK","rows","map","filteredPackage","value","name","err"],"sources":["../src/stars.ts"],"sourcesContent":["import { Response, Router } from 'express';\nimport _ from 'lodash';\n\nimport { HTTP_STATUS, USERS, errorUtils } from '@verdaccio/core';\nimport { Storage } from '@verdaccio/store';\nimport { Version } from '@verdaccio/types';\n\nimport { $NextFunctionVer, $RequestExtend } from '../types/custom';\n\nexport default function (route: Router, storage: Storage): void {\n route.get(\n '/-/_view/starredByUser',\n async (req: $RequestExtend, res: Response, next: $NextFunctionVer): Promise<void> => {\n const query: { key: string } = req.query;\n if (typeof query?.key !== 'string') {\n return next(errorUtils.getBadRequest('missing query key username'));\n }\n\n try {\n const localPackages: Version[] = await storage.getLocalDatabase();\n const filteredPackages: Version[] = localPackages.filter((localPackage: Version) =>\n _.keys(localPackage[USERS]).includes(query?.key.toString().replace(/['\"]+/g, ''))\n );\n\n res.status(HTTP_STATUS.OK);\n next({\n rows: filteredPackages.map((filteredPackage: Version) => ({\n value: filteredPackage.name,\n })),\n });\n } catch (err: any) {\n return next(err);\n }\n }\n );\n}\n"],"mappings":";;;;;;;AACA;;AAEA;;;;AAMe,kBAAUA,KAAV,EAAyBC,OAAzB,EAAiD;EAC9DD,KAAK,CAACE,GAAN,CACE,wBADF,EAEE,OAAOC,GAAP,EAA4BC,GAA5B,EAA2CC,IAA3C,KAAqF;IACnF,MAAMC,KAAsB,GAAGH,GAAG,CAACG,KAAnC;;IACA,IAAI,QAAOA,KAAP,aAAOA,KAAP,uBAAOA,KAAK,CAAEC,GAAd,MAAsB,QAA1B,EAAoC;MAClC,OAAOF,IAAI,CAACG,gBAAA,CAAWC,aAAX,CAAyB,4BAAzB,CAAD,CAAX;IACD;;IAED,IAAI;MACF,MAAMC,aAAwB,GAAG,MAAMT,OAAO,CAACU,gBAAR,EAAvC;MACA,MAAMC,gBAA2B,GAAGF,aAAa,CAACG,MAAd,CAAsBC,YAAD,IACvDC,eAAA,CAAEC,IAAF,CAAOF,YAAY,CAACG,WAAD,CAAnB,EAA4BC,QAA5B,CAAqCZ,KAArC,aAAqCA,KAArC,uBAAqCA,KAAK,CAAEC,GAAP,CAAWY,QAAX,GAAsBC,OAAtB,CAA8B,QAA9B,EAAwC,EAAxC,CAArC,CADkC,CAApC;MAIAhB,GAAG,CAACiB,MAAJ,CAAWC,iBAAA,CAAYC,EAAvB;MACAlB,IAAI,CAAC;QACHmB,IAAI,EAAEZ,gBAAgB,CAACa,GAAjB,CAAsBC,eAAD,KAA+B;UACxDC,KAAK,EAAED,eAAe,CAACE;QADiC,CAA/B,CAArB;MADH,CAAD,CAAJ;IAKD,CAZD,CAYE,OAAOC,GAAP,EAAiB;MACjB,OAAOxB,IAAI,CAACwB,GAAD,CAAX;IACD;EACF,CAvBH;AAyBD"}
|
package/build/user.js
CHANGED
|
@@ -80,6 +80,7 @@ function _default(route, auth, config) {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
res.status(_core.HTTP_STATUS.CREATED);
|
|
83
|
+
res.set(_core.HEADERS.CACHE_CONTROL, 'no-cache, no-store');
|
|
83
84
|
const message = (0, _utils.getAuthenticatedMessage)(req.remote_user.name);
|
|
84
85
|
debug('login: created user message %o', message);
|
|
85
86
|
return next({
|
|
@@ -121,6 +122,7 @@ function _default(route, auth, config) {
|
|
|
121
122
|
|
|
122
123
|
req.remote_user = user;
|
|
123
124
|
res.status(_core.HTTP_STATUS.CREATED);
|
|
125
|
+
res.set(_core.HEADERS.CACHE_CONTROL, 'no-cache, no-store');
|
|
124
126
|
debug('adduser: user has been created');
|
|
125
127
|
return next({
|
|
126
128
|
ok: `user '${req.body.name}' created`,
|
package/build/user.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.js","names":["debug","buildDebug","route","auth","config","get","req","res","next","message","getAuthenticatedMessage","remote_user","name","status","HTTP_STATUS","OK","ok","put","password","body","remoteName","authenticate","callbackAuthenticate","err","user","logger","trace","errorUtils","getCode","UNAUTHORIZED","API_ERROR","BAD_USERNAME_PASSWORD","restoredRemoteUser","createRemoteUser","groups","token","getApiToken","getUnauthorized","CREATED","validatioUtils","validatePassword","serverSettings","passwordValidationRegex","BAD_REQUEST","PASSWORD_SHORT","add_user","INTERNAL_ERROR","getConflict","undefined","mask","delete","API_MESSAGE","LOGGED_OUT"],"sources":["../src/user.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Response, Router } from 'express';\n\nimport { getApiToken } from '@verdaccio/auth';\nimport { Auth } from '@verdaccio/auth';\nimport { createRemoteUser } from '@verdaccio/config';\nimport {
|
|
1
|
+
{"version":3,"file":"user.js","names":["debug","buildDebug","route","auth","config","get","req","res","next","message","getAuthenticatedMessage","remote_user","name","status","HTTP_STATUS","OK","ok","put","password","body","remoteName","authenticate","callbackAuthenticate","err","user","logger","trace","errorUtils","getCode","UNAUTHORIZED","API_ERROR","BAD_USERNAME_PASSWORD","restoredRemoteUser","createRemoteUser","groups","token","getApiToken","getUnauthorized","CREATED","set","HEADERS","CACHE_CONTROL","validatioUtils","validatePassword","serverSettings","passwordValidationRegex","BAD_REQUEST","PASSWORD_SHORT","add_user","INTERNAL_ERROR","getConflict","undefined","mask","delete","API_MESSAGE","LOGGED_OUT"],"sources":["../src/user.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Response, Router } from 'express';\n\nimport { getApiToken } from '@verdaccio/auth';\nimport { Auth } from '@verdaccio/auth';\nimport { createRemoteUser } from '@verdaccio/config';\nimport {\n API_ERROR,\n API_MESSAGE,\n HEADERS,\n HTTP_STATUS,\n errorUtils,\n validatioUtils,\n} from '@verdaccio/core';\nimport { logger } from '@verdaccio/logger';\nimport { Config, RemoteUser } from '@verdaccio/types';\nimport { getAuthenticatedMessage, mask } from '@verdaccio/utils';\n\nimport { $NextFunctionVer, $RequestExtend } from '../types/custom';\n\nconst debug = buildDebug('verdaccio:api:user');\n\nexport default function (route: Router, auth: Auth, config: Config): void {\n route.get(\n '/-/user/:org_couchdb_user',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n debug('verifying user');\n const message = getAuthenticatedMessage(req.remote_user.name);\n debug('user authenticated message %o', message);\n res.status(HTTP_STATUS.OK);\n next({\n ok: message,\n });\n }\n );\n\n /**\n * \n * body example\n * req.body = {\n _id: \"org.couchdb.user:jjjj\",\n name: \"jjjj\",\n password: \"jjjj\",\n type: \"user\",\n roles: [],\n date: \"2022-07-08T15:51:04.002Z\",\n }\n * \n * @export\n * @param {Router} route\n * @param {Auth} auth\n * @param {Config} config\n */\n route.put(\n '/-/user/:org_couchdb_user/:_rev?/:revision?',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n const { name, password } = req.body;\n debug('login or adduser');\n const remoteName = req?.remote_user?.name;\n\n if (typeof remoteName !== 'undefined' && typeof name === 'string' && remoteName === name) {\n debug('login: no remote user detected');\n auth.authenticate(\n name,\n password,\n async function callbackAuthenticate(err, user): Promise<void> {\n if (err) {\n logger.trace(\n { name, err },\n 'authenticating for user @{username} failed. Error: @{err.message}'\n );\n return next(\n errorUtils.getCode(HTTP_STATUS.UNAUTHORIZED, API_ERROR.BAD_USERNAME_PASSWORD)\n );\n }\n\n const restoredRemoteUser: RemoteUser = createRemoteUser(name, user?.groups || []);\n const token = await getApiToken(auth, config, restoredRemoteUser, password);\n debug('login: new token');\n if (!token) {\n return next(errorUtils.getUnauthorized());\n }\n\n res.status(HTTP_STATUS.CREATED);\n res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');\n\n const message = getAuthenticatedMessage(req.remote_user.name);\n debug('login: created user message %o', message);\n\n return next({\n ok: message,\n token,\n });\n }\n );\n } else {\n if (\n validatioUtils.validatePassword(\n password,\n config?.serverSettings?.passwordValidationRegex\n ) === false\n ) {\n debug('adduser: invalid password');\n // eslint-disable-next-line new-cap\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.PASSWORD_SHORT));\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 token =\n name && password\n ? await getApiToken(auth, config, user as RemoteUser, password)\n : undefined;\n if (token) {\n debug('adduser: new token %o', mask(token as string, 4));\n }\n if (!token) {\n return next(errorUtils.getUnauthorized());\n }\n\n req.remote_user = user;\n res.status(HTTP_STATUS.CREATED);\n res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');\n debug('adduser: user has been created');\n return next({\n ok: `user '${req.body.name}' created`,\n token,\n });\n });\n }\n }\n );\n\n route.delete(\n '/-/user/token/*',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n res.status(HTTP_STATUS.OK);\n next({\n ok: API_MESSAGE.LOGGED_OUT,\n });\n }\n );\n}\n"],"mappings":"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"}
|
package/build/v1/token.js
CHANGED
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 { 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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
|
|
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","set","HEADERS","CACHE_CONTROL","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 { HEADERS, 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 res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');\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.34",
|
|
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.30",
|
|
34
|
+
"@verdaccio/config": "6.0.0-6-next.51",
|
|
35
|
+
"@verdaccio/core": "6.0.0-6-next.51",
|
|
36
|
+
"@verdaccio/logger": "6.0.0-6-next.19",
|
|
37
|
+
"@verdaccio/middleware": "6.0.0-6-next.30",
|
|
38
|
+
"@verdaccio/store": "6.0.0-6-next.31",
|
|
39
|
+
"@verdaccio/utils": "6.0.0-6-next.19",
|
|
40
40
|
"abortcontroller-polyfill": "1.7.5",
|
|
41
41
|
"cookies": "0.8.0",
|
|
42
42
|
"debug": "4.3.4",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@types/node": "16.11.65",
|
|
51
|
-
"@verdaccio/server": "6.0.0-6-next.
|
|
51
|
+
"@verdaccio/server": "6.0.0-6-next.40",
|
|
52
52
|
"@verdaccio/types": "11.0.0-6-next.17",
|
|
53
53
|
"@verdaccio/test-helper": "2.0.0-6-next.6",
|
|
54
54
|
"supertest": "6.3.0",
|
package/src/dist-tags.ts
CHANGED
|
@@ -98,24 +98,4 @@ export default function (route: Router, auth: Auth, storage: Storage): void {
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
);
|
|
101
|
-
|
|
102
|
-
route.post(
|
|
103
|
-
'/-/package/:package/dist-tags',
|
|
104
|
-
can('publish'),
|
|
105
|
-
async function (
|
|
106
|
-
req: $RequestExtend,
|
|
107
|
-
res: $ResponseExtend,
|
|
108
|
-
next: $NextFunctionVer
|
|
109
|
-
): Promise<void> {
|
|
110
|
-
try {
|
|
111
|
-
await storage.mergeTagsNext(req.params.package, req.body);
|
|
112
|
-
res.status(constants.HTTP_STATUS.CREATED);
|
|
113
|
-
return next({
|
|
114
|
-
ok: constants.API_MESSAGE.TAG_UPDATED,
|
|
115
|
-
});
|
|
116
|
-
} catch (err) {
|
|
117
|
-
next(err);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
);
|
|
121
101
|
}
|
package/src/stars.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Response, Router } from 'express';
|
|
2
2
|
import _ from 'lodash';
|
|
3
3
|
|
|
4
|
-
import { HTTP_STATUS, USERS } from '@verdaccio/core';
|
|
4
|
+
import { HTTP_STATUS, USERS, errorUtils } from '@verdaccio/core';
|
|
5
5
|
import { Storage } from '@verdaccio/store';
|
|
6
6
|
import { Version } from '@verdaccio/types';
|
|
7
7
|
|
|
@@ -11,13 +11,15 @@ export default function (route: Router, storage: Storage): void {
|
|
|
11
11
|
route.get(
|
|
12
12
|
'/-/_view/starredByUser',
|
|
13
13
|
async (req: $RequestExtend, res: Response, next: $NextFunctionVer): Promise<void> => {
|
|
14
|
-
const
|
|
14
|
+
const query: { key: string } = req.query;
|
|
15
|
+
if (typeof query?.key !== 'string') {
|
|
16
|
+
return next(errorUtils.getBadRequest('missing query key username'));
|
|
17
|
+
}
|
|
15
18
|
|
|
16
19
|
try {
|
|
17
|
-
const localPackages: Version[] = await storage.
|
|
18
|
-
|
|
20
|
+
const localPackages: Version[] = await storage.getLocalDatabase();
|
|
19
21
|
const filteredPackages: Version[] = localPackages.filter((localPackage: Version) =>
|
|
20
|
-
_.keys(localPackage[USERS]).includes(
|
|
22
|
+
_.keys(localPackage[USERS]).includes(query?.key.toString().replace(/['"]+/g, ''))
|
|
21
23
|
);
|
|
22
24
|
|
|
23
25
|
res.status(HTTP_STATUS.OK);
|
package/src/user.ts
CHANGED
|
@@ -4,7 +4,14 @@ import { Response, Router } from 'express';
|
|
|
4
4
|
import { getApiToken } from '@verdaccio/auth';
|
|
5
5
|
import { Auth } from '@verdaccio/auth';
|
|
6
6
|
import { createRemoteUser } from '@verdaccio/config';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
API_ERROR,
|
|
9
|
+
API_MESSAGE,
|
|
10
|
+
HEADERS,
|
|
11
|
+
HTTP_STATUS,
|
|
12
|
+
errorUtils,
|
|
13
|
+
validatioUtils,
|
|
14
|
+
} from '@verdaccio/core';
|
|
8
15
|
import { logger } from '@verdaccio/logger';
|
|
9
16
|
import { Config, RemoteUser } from '@verdaccio/types';
|
|
10
17
|
import { getAuthenticatedMessage, mask } from '@verdaccio/utils';
|
|
@@ -75,6 +82,7 @@ export default function (route: Router, auth: Auth, config: Config): void {
|
|
|
75
82
|
}
|
|
76
83
|
|
|
77
84
|
res.status(HTTP_STATUS.CREATED);
|
|
85
|
+
res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');
|
|
78
86
|
|
|
79
87
|
const message = getAuthenticatedMessage(req.remote_user.name);
|
|
80
88
|
debug('login: created user message %o', message);
|
|
@@ -124,6 +132,7 @@ export default function (route: Router, auth: Auth, config: Config): void {
|
|
|
124
132
|
|
|
125
133
|
req.remote_user = user;
|
|
126
134
|
res.status(HTTP_STATUS.CREATED);
|
|
135
|
+
res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');
|
|
127
136
|
debug('adduser: user has been created');
|
|
128
137
|
return next({
|
|
129
138
|
ok: `user '${req.body.name}' created`,
|
package/src/v1/token.ts
CHANGED
|
@@ -3,7 +3,7 @@ import _ from 'lodash';
|
|
|
3
3
|
|
|
4
4
|
import { getApiToken } from '@verdaccio/auth';
|
|
5
5
|
import { Auth } from '@verdaccio/auth';
|
|
6
|
-
import { HTTP_STATUS, SUPPORT_ERRORS, errorUtils } from '@verdaccio/core';
|
|
6
|
+
import { HEADERS, HTTP_STATUS, SUPPORT_ERRORS, errorUtils } from '@verdaccio/core';
|
|
7
7
|
import { logger } from '@verdaccio/logger';
|
|
8
8
|
import { Storage } from '@verdaccio/store';
|
|
9
9
|
import { Config, RemoteUser, Token } from '@verdaccio/types';
|
|
@@ -102,6 +102,7 @@ export default function (route: Router, auth: Auth, storage: Storage, config: Co
|
|
|
102
102
|
|
|
103
103
|
await storage.saveToken(saveToken);
|
|
104
104
|
logger.debug({ key, name }, 'token @{key} was created for user @{name}');
|
|
105
|
+
res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');
|
|
105
106
|
return next(
|
|
106
107
|
normalizeToken({
|
|
107
108
|
token,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
generatePackageMetadata,
|
|
12
12
|
initializeServer as initializeServerHelper,
|
|
13
13
|
} from '@verdaccio/test-helper';
|
|
14
|
-
import { GenericBody } from '@verdaccio/types';
|
|
14
|
+
import { GenericBody, PackageUsers } from '@verdaccio/types';
|
|
15
15
|
import { buildToken, generateRandomHexString } from '@verdaccio/utils';
|
|
16
16
|
|
|
17
17
|
import apiMiddleware from '../../src';
|
|
@@ -39,6 +39,7 @@ export function createUser(app, name: string, password: string): supertest.Test
|
|
|
39
39
|
password: password,
|
|
40
40
|
})
|
|
41
41
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
|
42
|
+
.expect(HEADERS.CACHE_CONTROL, 'no-cache, no-store')
|
|
42
43
|
.expect(HTTP_STATUS.CREATED);
|
|
43
44
|
}
|
|
44
45
|
|
|
@@ -91,16 +92,54 @@ export function publishVersion(
|
|
|
91
92
|
app,
|
|
92
93
|
pkgName: string,
|
|
93
94
|
version: string,
|
|
94
|
-
distTags?: GenericBody
|
|
95
|
+
distTags?: GenericBody,
|
|
96
|
+
token?: string
|
|
95
97
|
): supertest.Test {
|
|
96
98
|
const pkgMetadata = generatePackageMetadata(pkgName, version, distTags);
|
|
97
99
|
|
|
98
|
-
|
|
100
|
+
const test = supertest(app)
|
|
99
101
|
.put(`/${encodeURIComponent(pkgName)}`)
|
|
100
102
|
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
|
101
103
|
.send(JSON.stringify(pkgMetadata))
|
|
102
104
|
.set('accept', HEADERS.GZIP)
|
|
103
105
|
.set(HEADER_TYPE.ACCEPT_ENCODING, HEADERS.JSON);
|
|
106
|
+
|
|
107
|
+
if (typeof token === 'string') {
|
|
108
|
+
test.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return test;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function starPackage(
|
|
115
|
+
app,
|
|
116
|
+
options: {
|
|
117
|
+
users: PackageUsers;
|
|
118
|
+
name: string;
|
|
119
|
+
_rev: string;
|
|
120
|
+
_id?: string;
|
|
121
|
+
},
|
|
122
|
+
token?: string
|
|
123
|
+
): supertest.Test {
|
|
124
|
+
const { _rev, _id, users } = options;
|
|
125
|
+
const starManifest = {
|
|
126
|
+
_rev,
|
|
127
|
+
_id,
|
|
128
|
+
users,
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const test = supertest(app)
|
|
132
|
+
.put(`/${encodeURIComponent(options.name)}`)
|
|
133
|
+
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
|
134
|
+
.send(JSON.stringify(starManifest))
|
|
135
|
+
.set('accept', HEADERS.GZIP)
|
|
136
|
+
.set(HEADER_TYPE.ACCEPT_ENCODING, HEADERS.JSON);
|
|
137
|
+
|
|
138
|
+
if (typeof token === 'string') {
|
|
139
|
+
test.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return test;
|
|
104
143
|
}
|
|
105
144
|
|
|
106
145
|
export function getDisTags(app, pkgName) {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
auth:
|
|
2
|
+
htpasswd:
|
|
3
|
+
file: ./htpasswd-star
|
|
4
|
+
web:
|
|
5
|
+
enable: true
|
|
6
|
+
title: verdaccio
|
|
7
|
+
|
|
8
|
+
uplinks:
|
|
9
|
+
npmjs:
|
|
10
|
+
url: https://registry.npmjs.org/
|
|
11
|
+
|
|
12
|
+
log: { type: stdout, format: pretty, level: info }
|
|
13
|
+
|
|
14
|
+
packages:
|
|
15
|
+
'@*/*':
|
|
16
|
+
access: $all
|
|
17
|
+
publish: $authenticated
|
|
18
|
+
unpublish: $authenticated
|
|
19
|
+
proxy: npmjs
|
|
20
|
+
'**':
|
|
21
|
+
access: $all
|
|
22
|
+
publish: $authenticated
|
|
23
|
+
unpublish: $authenticated
|
|
24
|
+
proxy: npmjs
|
|
25
|
+
|
|
26
|
+
_debug: true
|
|
@@ -6,38 +6,8 @@ import { HTTP_STATUS } from '@verdaccio/core';
|
|
|
6
6
|
import { API_ERROR, API_MESSAGE, HEADERS, HEADER_TYPE } from '@verdaccio/core';
|
|
7
7
|
import { generatePackageMetadata, generateRemotePackageMetadata } from '@verdaccio/test-helper';
|
|
8
8
|
|
|
9
|
-
import { $RequestExtend, $ResponseExtend } from '../../types/custom';
|
|
10
9
|
import { getPackage, initializeServer, publishVersion } from './_helper';
|
|
11
10
|
|
|
12
|
-
const mockApiJWTmiddleware = jest.fn(
|
|
13
|
-
() =>
|
|
14
|
-
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
|
15
|
-
req.remote_user = { name: 'foo', groups: [], real_groups: [] };
|
|
16
|
-
_next();
|
|
17
|
-
}
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
jest.mock('@verdaccio/auth', () => ({
|
|
21
|
-
Auth: class {
|
|
22
|
-
apiJWTmiddleware() {
|
|
23
|
-
return mockApiJWTmiddleware();
|
|
24
|
-
}
|
|
25
|
-
init() {
|
|
26
|
-
return Promise.resolve();
|
|
27
|
-
}
|
|
28
|
-
allow_access(_d, f_, cb) {
|
|
29
|
-
cb(null, true);
|
|
30
|
-
}
|
|
31
|
-
allow_publish(_d, f_, cb) {
|
|
32
|
-
cb(null, true);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
allow_unpublish(_d, f_, cb) {
|
|
36
|
-
cb(null, true);
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
}));
|
|
40
|
-
|
|
41
11
|
describe('publish', () => {
|
|
42
12
|
describe('handle errors', () => {
|
|
43
13
|
const pkgName = 'test';
|
|
@@ -80,6 +50,22 @@ describe('publish', () => {
|
|
|
80
50
|
});
|
|
81
51
|
});
|
|
82
52
|
});
|
|
53
|
+
|
|
54
|
+
test.each([['foo', '@scope/foo']])(
|
|
55
|
+
'should fails on publish a duplicated package',
|
|
56
|
+
async (pkgName) => {
|
|
57
|
+
const app = await initializeServer('publish.yaml');
|
|
58
|
+
await publishVersion(app, pkgName, '1.0.0');
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
publishVersion(app, pkgName, '1.0.0')
|
|
61
|
+
.expect(HTTP_STATUS.CONFLICT)
|
|
62
|
+
.then((response) => {
|
|
63
|
+
expect(response.body.error).toEqual(API_ERROR.PACKAGE_EXIST);
|
|
64
|
+
resolve(response);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
);
|
|
83
69
|
});
|
|
84
70
|
|
|
85
71
|
describe('publish a package', () => {
|
|
@@ -141,6 +127,7 @@ describe('publish', () => {
|
|
|
141
127
|
});
|
|
142
128
|
});
|
|
143
129
|
});
|
|
130
|
+
|
|
144
131
|
describe('proxies setup', () => {
|
|
145
132
|
test.each([['foo', '@scope%2Ffoo']])(
|
|
146
133
|
'should publish a a patch package that already exist on a remote',
|
|
@@ -172,22 +159,6 @@ describe('publish', () => {
|
|
|
172
159
|
});
|
|
173
160
|
});
|
|
174
161
|
|
|
175
|
-
test.each([['foo', '@scope/foo']])(
|
|
176
|
-
'should fails on publish a duplicated package',
|
|
177
|
-
async (pkgName) => {
|
|
178
|
-
const app = await initializeServer('publish.yaml');
|
|
179
|
-
await publishVersion(app, pkgName, '1.0.0');
|
|
180
|
-
return new Promise((resolve) => {
|
|
181
|
-
publishVersion(app, pkgName, '1.0.0')
|
|
182
|
-
.expect(HTTP_STATUS.CONFLICT)
|
|
183
|
-
.then((response) => {
|
|
184
|
-
expect(response.body.error).toEqual(API_ERROR.PACKAGE_EXIST);
|
|
185
|
-
resolve(response);
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
);
|
|
190
|
-
|
|
191
162
|
describe('unpublish a package', () => {
|
|
192
163
|
test.each([['foo', '@scope/foo']])('should unpublish entirely a package', async (pkgName) => {
|
|
193
164
|
const app = await initializeServer('publish.yaml');
|
|
@@ -257,6 +228,4 @@ describe('publish', () => {
|
|
|
257
228
|
}
|
|
258
229
|
);
|
|
259
230
|
});
|
|
260
|
-
|
|
261
|
-
describe('star a package', () => {});
|
|
262
231
|
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import nock from 'nock';
|
|
2
|
+
import supertest from 'supertest';
|
|
3
|
+
|
|
4
|
+
import { HTTP_STATUS } from '@verdaccio/core';
|
|
5
|
+
import { HEADERS, HEADER_TYPE } from '@verdaccio/core';
|
|
6
|
+
|
|
7
|
+
import { getNewToken, getPackage, initializeServer, publishVersion, starPackage } from './_helper';
|
|
8
|
+
|
|
9
|
+
describe('star', () => {
|
|
10
|
+
test.each([['foo', '@scope%2Ffoo']])(
|
|
11
|
+
'should list stared packages for an user',
|
|
12
|
+
async (pkgName) => {
|
|
13
|
+
const userLogged = 'jota_token';
|
|
14
|
+
nock('https://registry.npmjs.org').get(`/${pkgName}`).reply(404);
|
|
15
|
+
const app = await initializeServer('star.yaml');
|
|
16
|
+
const token = await getNewToken(app, { name: userLogged, password: 'secretPass' });
|
|
17
|
+
await publishVersion(app, pkgName, '1.0.0', undefined, token).expect(HTTP_STATUS.CREATED);
|
|
18
|
+
await publishVersion(app, 'pkg-1', '1.0.0', undefined, token).expect(HTTP_STATUS.CREATED);
|
|
19
|
+
await publishVersion(app, 'pkg-2', '1.0.0', undefined, token).expect(HTTP_STATUS.CREATED);
|
|
20
|
+
const manifest = await getPackage(app, '', decodeURIComponent(pkgName));
|
|
21
|
+
await starPackage(
|
|
22
|
+
app,
|
|
23
|
+
{
|
|
24
|
+
_rev: manifest.body._rev,
|
|
25
|
+
_id: manifest.body.id,
|
|
26
|
+
name: pkgName,
|
|
27
|
+
users: { [userLogged]: true },
|
|
28
|
+
},
|
|
29
|
+
token
|
|
30
|
+
).expect(HTTP_STATUS.CREATED);
|
|
31
|
+
await starPackage(
|
|
32
|
+
app,
|
|
33
|
+
{
|
|
34
|
+
_rev: manifest.body._rev,
|
|
35
|
+
_id: manifest.body.id,
|
|
36
|
+
name: 'pkg-1',
|
|
37
|
+
users: { [userLogged]: true },
|
|
38
|
+
},
|
|
39
|
+
token
|
|
40
|
+
).expect(HTTP_STATUS.CREATED);
|
|
41
|
+
await starPackage(
|
|
42
|
+
app,
|
|
43
|
+
{
|
|
44
|
+
_rev: manifest.body._rev,
|
|
45
|
+
_id: manifest.body.id,
|
|
46
|
+
name: 'pkg-2',
|
|
47
|
+
users: { [userLogged]: true },
|
|
48
|
+
},
|
|
49
|
+
token
|
|
50
|
+
).expect(HTTP_STATUS.CREATED);
|
|
51
|
+
const resp = await supertest(app)
|
|
52
|
+
.get(`/-/_view/starredByUser?key=%22jota_token%22`)
|
|
53
|
+
.set('Accept', HEADERS.JSON)
|
|
54
|
+
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
|
55
|
+
.expect(HTTP_STATUS.OK);
|
|
56
|
+
expect(resp.body.rows).toHaveLength(3);
|
|
57
|
+
expect(resp.body.rows).toEqual([{ value: 'foo' }, { value: 'pkg-1' }, { value: 'pkg-2' }]);
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
test.each([['foo']])('should requires parameters', async (pkgName) => {
|
|
62
|
+
const userLogged = 'jota_token';
|
|
63
|
+
nock('https://registry.npmjs.org').get(`/${pkgName}`).reply(404);
|
|
64
|
+
const app = await initializeServer('star.yaml');
|
|
65
|
+
const token = await getNewToken(app, { name: userLogged, password: 'secretPass' });
|
|
66
|
+
await publishVersion(app, pkgName, '1.0.0', undefined, token).expect(HTTP_STATUS.CREATED);
|
|
67
|
+
return supertest(app)
|
|
68
|
+
.get(`/-/_view/starredByUser?key_xxxxx=other`)
|
|
69
|
+
.set('Accept', HEADERS.JSON)
|
|
70
|
+
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
|
71
|
+
.expect(HTTP_STATUS.BAD_REQUEST);
|
|
72
|
+
});
|
|
73
|
+
});
|
package/types/custom.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { NextFunction, Request, Response } from 'express';
|
|
|
2
2
|
|
|
3
3
|
import { Logger, RemoteUser } from '@verdaccio/types';
|
|
4
4
|
|
|
5
|
-
export type $RequestExtend = Request & { remote_user?: any; log: Logger };
|
|
5
|
+
export type $RequestExtend = Request & { remote_user?: any; log: Logger; query?: { key: string } };
|
|
6
6
|
export type $ResponseExtend = Response & { cookies?: any };
|
|
7
7
|
export type $NextFunctionVer = NextFunction & any;
|
|
8
8
|
|
package/build/star.d.ts
DELETED
package/build/star.js
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = _default;
|
|
7
|
-
|
|
8
|
-
var _debug = _interopRequireDefault(require("debug"));
|
|
9
|
-
|
|
10
|
-
var _lodash = _interopRequireDefault(require("lodash"));
|
|
11
|
-
|
|
12
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
15
|
-
const debug = (0, _debug.default)('verdaccio:api:publish:star');
|
|
16
|
-
|
|
17
|
-
function _default(storage) {
|
|
18
|
-
const validateInputs = (newUsers, localUsers, username, isStar) => {
|
|
19
|
-
const isExistlocalUsers = _lodash.default.isNil(localUsers[username]) === false;
|
|
20
|
-
|
|
21
|
-
if (isStar && isExistlocalUsers && localUsers[username]) {
|
|
22
|
-
return true;
|
|
23
|
-
} else if (!isStar && isExistlocalUsers) {
|
|
24
|
-
return false;
|
|
25
|
-
} else if (!isStar && !isExistlocalUsers) {
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return false;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
return (req, res, next) => {
|
|
33
|
-
const name = req.params.package;
|
|
34
|
-
debug('starring a package for %o', name); // const afterChangePackage = function (err?: Error) {
|
|
35
|
-
// if (err) {
|
|
36
|
-
// debug('error on update package for %o', name);
|
|
37
|
-
// return next(err);
|
|
38
|
-
// }
|
|
39
|
-
// debug('succes update package for %o', name);
|
|
40
|
-
// res.status(HTTP_STATUS.OK);
|
|
41
|
-
// next({
|
|
42
|
-
// success: true,
|
|
43
|
-
// });
|
|
44
|
-
// };
|
|
45
|
-
|
|
46
|
-
debug('get package info package for %o', name); // @ts-ignore
|
|
47
|
-
// storage.getPackage({
|
|
48
|
-
// name,
|
|
49
|
-
// req,
|
|
50
|
-
// callback: function (err, info) {
|
|
51
|
-
// if (err) {
|
|
52
|
-
// debug('error on get package info package for %o', name);
|
|
53
|
-
// return next(err);
|
|
54
|
-
// }
|
|
55
|
-
// const newStarUser = req.body[USERS];
|
|
56
|
-
// const remoteUsername = req.remote_user.name;
|
|
57
|
-
// const localStarUsers = info[USERS];
|
|
58
|
-
// // Check is star or unstar
|
|
59
|
-
// const isStar = Object.keys(newStarUser).includes(remoteUsername);
|
|
60
|
-
// debug('is start? %o', isStar);
|
|
61
|
-
// if (
|
|
62
|
-
// _.isNil(localStarUsers) === false &&
|
|
63
|
-
// validateInputs(newStarUser, localStarUsers, remoteUsername, isStar)
|
|
64
|
-
// ) {
|
|
65
|
-
// return afterChangePackage();
|
|
66
|
-
// }
|
|
67
|
-
// const users = isStar
|
|
68
|
-
// ? {
|
|
69
|
-
// ...localStarUsers,
|
|
70
|
-
// [remoteUsername]: true,
|
|
71
|
-
// }
|
|
72
|
-
// : _.reduce(
|
|
73
|
-
// localStarUsers,
|
|
74
|
-
// (users, value, key) => {
|
|
75
|
-
// if (key !== remoteUsername) {
|
|
76
|
-
// users[key] = value;
|
|
77
|
-
// }
|
|
78
|
-
// return users;
|
|
79
|
-
// },
|
|
80
|
-
// {}
|
|
81
|
-
// );
|
|
82
|
-
// debug('update package for %o', name);
|
|
83
|
-
// storage.changePackage(name, { ...info, users }, req.body._rev, function (err) {
|
|
84
|
-
// afterChangePackage(err);
|
|
85
|
-
// });
|
|
86
|
-
// },
|
|
87
|
-
// });
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
//# sourceMappingURL=star.js.map
|
package/build/star.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"star.js","names":["debug","buildDebug","storage","validateInputs","newUsers","localUsers","username","isStar","isExistlocalUsers","_","isNil","req","res","next","name","params","package"],"sources":["../src/star.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\nimport buildDebug from 'debug';\nimport { Response } from 'express';\nimport _ from 'lodash';\n\nimport { HTTP_STATUS, USERS } from '@verdaccio/core';\nimport { Storage } from '@verdaccio/store';\n\nimport { $NextFunctionVer, $RequestExtend } from '../types/custom';\n\nconst debug = buildDebug('verdaccio:api:publish:star');\n\nexport default function (\n storage: Storage\n): (req: $RequestExtend, res: Response, next: $NextFunctionVer) => void {\n const validateInputs = (newUsers, localUsers, username, isStar): boolean => {\n const isExistlocalUsers = _.isNil(localUsers[username]) === false;\n if (isStar && isExistlocalUsers && localUsers[username]) {\n return true;\n } else if (!isStar && isExistlocalUsers) {\n return false;\n } else if (!isStar && !isExistlocalUsers) {\n return true;\n }\n return false;\n };\n\n return (req: $RequestExtend, res: Response, next: $NextFunctionVer): void => {\n const name = req.params.package;\n debug('starring a package for %o', name);\n // const afterChangePackage = function (err?: Error) {\n // if (err) {\n // debug('error on update package for %o', name);\n // return next(err);\n // }\n\n // debug('succes update package for %o', name);\n // res.status(HTTP_STATUS.OK);\n // next({\n // success: true,\n // });\n // };\n\n debug('get package info package for %o', name);\n // @ts-ignore\n // storage.getPackage({\n // name,\n // req,\n // callback: function (err, info) {\n // if (err) {\n // debug('error on get package info package for %o', name);\n // return next(err);\n // }\n // const newStarUser = req.body[USERS];\n // const remoteUsername = req.remote_user.name;\n // const localStarUsers = info[USERS];\n // // Check is star or unstar\n // const isStar = Object.keys(newStarUser).includes(remoteUsername);\n // debug('is start? %o', isStar);\n // if (\n // _.isNil(localStarUsers) === false &&\n // validateInputs(newStarUser, localStarUsers, remoteUsername, isStar)\n // ) {\n // return afterChangePackage();\n // }\n // const users = isStar\n // ? {\n // ...localStarUsers,\n // [remoteUsername]: true,\n // }\n // : _.reduce(\n // localStarUsers,\n // (users, value, key) => {\n // if (key !== remoteUsername) {\n // users[key] = value;\n // }\n // return users;\n // },\n // {}\n // );\n // debug('update package for %o', name);\n // storage.changePackage(name, { ...info, users }, req.body._rev, function (err) {\n // afterChangePackage(err);\n // });\n // },\n // });\n };\n}\n"],"mappings":";;;;;;;AACA;;AAEA;;;;AAHA;AAUA,MAAMA,KAAK,GAAG,IAAAC,cAAA,EAAW,4BAAX,CAAd;;AAEe,kBACbC,OADa,EAEyD;EACtE,MAAMC,cAAc,GAAG,CAACC,QAAD,EAAWC,UAAX,EAAuBC,QAAvB,EAAiCC,MAAjC,KAAqD;IAC1E,MAAMC,iBAAiB,GAAGC,eAAA,CAAEC,KAAF,CAAQL,UAAU,CAACC,QAAD,CAAlB,MAAkC,KAA5D;;IACA,IAAIC,MAAM,IAAIC,iBAAV,IAA+BH,UAAU,CAACC,QAAD,CAA7C,EAAyD;MACvD,OAAO,IAAP;IACD,CAFD,MAEO,IAAI,CAACC,MAAD,IAAWC,iBAAf,EAAkC;MACvC,OAAO,KAAP;IACD,CAFM,MAEA,IAAI,CAACD,MAAD,IAAW,CAACC,iBAAhB,EAAmC;MACxC,OAAO,IAAP;IACD;;IACD,OAAO,KAAP;EACD,CAVD;;EAYA,OAAO,CAACG,GAAD,EAAsBC,GAAtB,EAAqCC,IAArC,KAAsE;IAC3E,MAAMC,IAAI,GAAGH,GAAG,CAACI,MAAJ,CAAWC,OAAxB;IACAhB,KAAK,CAAC,2BAAD,EAA8Bc,IAA9B,CAAL,CAF2E,CAG3E;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;;IAEAd,KAAK,CAAC,iCAAD,EAAoCc,IAApC,CAAL,CAhB2E,CAiB3E;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;EACD,CA3DD;AA4DD"}
|
package/src/star.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
-
import buildDebug from 'debug';
|
|
3
|
-
import { Response } from 'express';
|
|
4
|
-
import _ from 'lodash';
|
|
5
|
-
|
|
6
|
-
import { HTTP_STATUS, USERS } from '@verdaccio/core';
|
|
7
|
-
import { Storage } from '@verdaccio/store';
|
|
8
|
-
|
|
9
|
-
import { $NextFunctionVer, $RequestExtend } from '../types/custom';
|
|
10
|
-
|
|
11
|
-
const debug = buildDebug('verdaccio:api:publish:star');
|
|
12
|
-
|
|
13
|
-
export default function (
|
|
14
|
-
storage: Storage
|
|
15
|
-
): (req: $RequestExtend, res: Response, next: $NextFunctionVer) => void {
|
|
16
|
-
const validateInputs = (newUsers, localUsers, username, isStar): boolean => {
|
|
17
|
-
const isExistlocalUsers = _.isNil(localUsers[username]) === false;
|
|
18
|
-
if (isStar && isExistlocalUsers && localUsers[username]) {
|
|
19
|
-
return true;
|
|
20
|
-
} else if (!isStar && isExistlocalUsers) {
|
|
21
|
-
return false;
|
|
22
|
-
} else if (!isStar && !isExistlocalUsers) {
|
|
23
|
-
return true;
|
|
24
|
-
}
|
|
25
|
-
return false;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
return (req: $RequestExtend, res: Response, next: $NextFunctionVer): void => {
|
|
29
|
-
const name = req.params.package;
|
|
30
|
-
debug('starring a package for %o', name);
|
|
31
|
-
// const afterChangePackage = function (err?: Error) {
|
|
32
|
-
// if (err) {
|
|
33
|
-
// debug('error on update package for %o', name);
|
|
34
|
-
// return next(err);
|
|
35
|
-
// }
|
|
36
|
-
|
|
37
|
-
// debug('succes update package for %o', name);
|
|
38
|
-
// res.status(HTTP_STATUS.OK);
|
|
39
|
-
// next({
|
|
40
|
-
// success: true,
|
|
41
|
-
// });
|
|
42
|
-
// };
|
|
43
|
-
|
|
44
|
-
debug('get package info package for %o', name);
|
|
45
|
-
// @ts-ignore
|
|
46
|
-
// storage.getPackage({
|
|
47
|
-
// name,
|
|
48
|
-
// req,
|
|
49
|
-
// callback: function (err, info) {
|
|
50
|
-
// if (err) {
|
|
51
|
-
// debug('error on get package info package for %o', name);
|
|
52
|
-
// return next(err);
|
|
53
|
-
// }
|
|
54
|
-
// const newStarUser = req.body[USERS];
|
|
55
|
-
// const remoteUsername = req.remote_user.name;
|
|
56
|
-
// const localStarUsers = info[USERS];
|
|
57
|
-
// // Check is star or unstar
|
|
58
|
-
// const isStar = Object.keys(newStarUser).includes(remoteUsername);
|
|
59
|
-
// debug('is start? %o', isStar);
|
|
60
|
-
// if (
|
|
61
|
-
// _.isNil(localStarUsers) === false &&
|
|
62
|
-
// validateInputs(newStarUser, localStarUsers, remoteUsername, isStar)
|
|
63
|
-
// ) {
|
|
64
|
-
// return afterChangePackage();
|
|
65
|
-
// }
|
|
66
|
-
// const users = isStar
|
|
67
|
-
// ? {
|
|
68
|
-
// ...localStarUsers,
|
|
69
|
-
// [remoteUsername]: true,
|
|
70
|
-
// }
|
|
71
|
-
// : _.reduce(
|
|
72
|
-
// localStarUsers,
|
|
73
|
-
// (users, value, key) => {
|
|
74
|
-
// if (key !== remoteUsername) {
|
|
75
|
-
// users[key] = value;
|
|
76
|
-
// }
|
|
77
|
-
// return users;
|
|
78
|
-
// },
|
|
79
|
-
// {}
|
|
80
|
-
// );
|
|
81
|
-
// debug('update package for %o', name);
|
|
82
|
-
// storage.changePackage(name, { ...info, users }, req.body._rev, function (err) {
|
|
83
|
-
// afterChangePackage(err);
|
|
84
|
-
// });
|
|
85
|
-
// },
|
|
86
|
-
// });
|
|
87
|
-
};
|
|
88
|
-
}
|