@verdaccio/api 6.0.0-6-next.42 → 6.0.0-6-next.43

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 CHANGED
@@ -1,5 +1,22 @@
1
1
  # @verdaccio/api
2
2
 
3
+ ## 6.0.0-6-next.43
4
+
5
+ ### Minor Changes
6
+
7
+ - 45c03819: refactor: render html middleware
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [45c03819]
12
+ - @verdaccio/config@6.0.0-6-next.60
13
+ - @verdaccio/middleware@6.0.0-6-next.39
14
+ - @verdaccio/store@6.0.0-6-next.40
15
+ - @verdaccio/auth@6.0.0-6-next.39
16
+ - @verdaccio/core@6.0.0-6-next.60
17
+ - @verdaccio/logger@6.0.0-6-next.28
18
+ - @verdaccio/utils@6.0.0-6-next.28
19
+
3
20
  ## 6.0.0-6-next.42
4
21
 
5
22
  ### Patch Changes
package/build/user.js CHANGED
@@ -9,11 +9,12 @@ var _auth = require("@verdaccio/auth");
9
9
  var _config = require("@verdaccio/config");
10
10
  var _core = require("@verdaccio/core");
11
11
  var _logger = require("@verdaccio/logger");
12
+ var _middleware = require("@verdaccio/middleware");
12
13
  var _utils = require("@verdaccio/utils");
13
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
15
  const debug = (0, _debug.default)('verdaccio:api:user');
15
16
  function _default(route, auth, config) {
16
- route.get('/-/user/:org_couchdb_user', function (req, res, next) {
17
+ route.get('/-/user/:org_couchdb_user', (0, _middleware.rateLimit)(config === null || config === void 0 ? void 0 : config.userRateLimit), function (req, res, next) {
17
18
  debug('verifying user');
18
19
  const message = (0, _utils.getAuthenticatedMessage)(req.remote_user.name);
19
20
  debug('user authenticated message %o', message);
@@ -40,7 +41,7 @@ function _default(route, auth, config) {
40
41
  * @param {Auth} auth
41
42
  * @param {Config} config
42
43
  */
43
- route.put('/-/user/:org_couchdb_user/:_rev?/:revision?', function (req, res, next) {
44
+ route.put('/-/user/:org_couchdb_user/:_rev?/:revision?', (0, _middleware.rateLimit)(config === null || config === void 0 ? void 0 : config.userRateLimit), function (req, res, next) {
44
45
  var _req$remote_user;
45
46
  const {
46
47
  name,
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","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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"}
1
+ {"version":3,"file":"user.js","names":["debug","buildDebug","route","auth","config","get","rateLimit","userRateLimit","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 { rateLimit } from '@verdaccio/middleware';\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 rateLimit(config?.userRateLimit),\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 rateLimit(config?.userRateLimit),\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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"}
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = _default;
7
7
  var _lodash = _interopRequireDefault(require("lodash"));
8
8
  var _core = require("@verdaccio/core");
9
+ var _middleware = require("@verdaccio/middleware");
9
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
11
  function _default(route, auth, config) {
11
12
  function buildProfile(name) {
@@ -20,7 +21,7 @@ function _default(route, auth, config) {
20
21
  fullname: ''
21
22
  };
22
23
  }
23
- route.get('/-/npm/v1/user', function (req, res, next) {
24
+ route.get('/-/npm/v1/user', (0, _middleware.rateLimit)(config === null || config === void 0 ? void 0 : config.userRateLimit), function (req, res, next) {
24
25
  if (_lodash.default.isNil(req.remote_user.name) === false) {
25
26
  return next(buildProfile(req.remote_user.name));
26
27
  }
@@ -29,7 +30,7 @@ function _default(route, auth, config) {
29
30
  message: _core.API_ERROR.MUST_BE_LOGGED
30
31
  });
31
32
  });
32
- route.post('/-/npm/v1/user', function (req, res, next) {
33
+ route.post('/-/npm/v1/user', (0, _middleware.rateLimit)(config === null || config === void 0 ? void 0 : config.userRateLimit), function (req, res, next) {
33
34
  if (_lodash.default.isNil(req.remote_user.name)) {
34
35
  res.status(_core.HTTP_STATUS.UNAUTHORIZED);
35
36
  return next({
@@ -1 +1 @@
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
+ {"version":3,"file":"profile.js","names":["route","auth","config","buildProfile","name","tfa","email","email_verified","created","updated","cidr_whitelist","fullname","get","rateLimit","userRateLimit","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 { rateLimit } from '@verdaccio/middleware';\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 rateLimit(config?.userRateLimit),\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 rateLimit(config?.userRateLimit),\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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"}
package/build/v1/token.js CHANGED
@@ -8,6 +8,7 @@ var _lodash = _interopRequireDefault(require("lodash"));
8
8
  var _auth = require("@verdaccio/auth");
9
9
  var _core = require("@verdaccio/core");
10
10
  var _logger = require("@verdaccio/logger");
11
+ var _middleware = require("@verdaccio/middleware");
11
12
  var _utils = require("@verdaccio/utils");
12
13
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
14
  function normalizeToken(token) {
@@ -19,7 +20,7 @@ function normalizeToken(token) {
19
20
 
20
21
  // https://github.com/npm/npm-profile/blob/latest/lib/index.js
21
22
  function _default(route, auth, storage, config) {
22
- route.get('/-/npm/v1/tokens', async function (req, res, next) {
23
+ route.get('/-/npm/v1/tokens', (0, _middleware.rateLimit)(config === null || config === void 0 ? void 0 : config.userRateLimit), async function (req, res, next) {
23
24
  const {
24
25
  name
25
26
  } = req.remote_user;
@@ -48,7 +49,7 @@ function _default(route, auth, storage, config) {
48
49
  }
49
50
  return next(_core.errorUtils.getUnauthorized());
50
51
  });
51
- route.post('/-/npm/v1/tokens', function (req, res, next) {
52
+ route.post('/-/npm/v1/tokens', (0, _middleware.rateLimit)(config === null || config === void 0 ? void 0 : config.userRateLimit), function (req, res, next) {
52
53
  const {
53
54
  password,
54
55
  readonly,
@@ -114,7 +115,7 @@ function _default(route, auth, storage, config) {
114
115
  }
115
116
  });
116
117
  });
117
- route.delete('/-/npm/v1/tokens/token/:tokenKey', async (req, res, next) => {
118
+ route.delete('/-/npm/v1/tokens/token/:tokenKey', (0, _middleware.rateLimit)(config === null || config === void 0 ? void 0 : config.userRateLimit), async (req, res, next) => {
118
119
  const {
119
120
  params: {
120
121
  tokenKey
@@ -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","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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"}
1
+ {"version":3,"file":"token.js","names":["normalizeToken","token","created","Date","toISOString","route","auth","storage","config","get","rateLimit","userRateLimit","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 { rateLimit } from '@verdaccio/middleware';\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 rateLimit(config?.userRateLimit),\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 rateLimit(config?.userRateLimit),\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 rateLimit(config?.userRateLimit),\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":";;;;;;AACA;AAEA;AAEA;AACA;AACA;AAGA;AAAqD;AAQrD,SAASA,cAAc,CAACC,KAAY,EAAkB;EACpD,OAAO;IACL,GAAGA,KAAK;IACRC,OAAO,EAAE,IAAIC,IAAI,CAACF,KAAK,CAACC,OAAO,CAAC,CAACE,WAAW;EAC9C,CAAC;AACH;;AAEA;AACe,kBAAUC,KAAa,EAAEC,IAAU,EAAEC,OAAgB,EAAEC,MAAc,EAAQ;EAC1FH,KAAK,CAACI,GAAG,CACP,kBAAkB,EAClB,IAAAC,qBAAS,EAACF,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEG,aAAa,CAAC,EAChC,gBAAgBC,GAAmB,EAAEC,GAAa,EAAEC,IAAsB,EAAE;IAC1E,MAAM;MAAEC;IAAK,CAAC,GAAGH,GAAG,CAACI,WAAW;IAEhC,IAAIC,eAAC,CAACC,KAAK,CAACH,IAAI,CAAC,KAAK,KAAK,EAAE;MAC3B,IAAI;QACF,MAAMI,MAAM,GAAG,MAAMZ,OAAO,CAACa,UAAU,CAAC;UAAEC,IAAI,EAAEN;QAAK,CAAC,CAAC;QACvD,MAAMO,WAAW,GAAGH,MAAM,CAACI,MAAM;QACjCC,cAAM,CAACC,KAAK,CAAC;UAAEH;QAAY,CAAC,EAAE,sCAAsC,CAAC;QAErET,GAAG,CAACa,MAAM,CAACC,iBAAW,CAACC,EAAE,CAAC;QAC1B,OAAOd,IAAI,CAAC;UACVe,OAAO,EAAEV,MAAM,CAACW,GAAG,CAAC9B,cAAc,CAAC;UACnC+B,IAAI,EAAE;YACJjB,IAAI,EAAE,EAAE,CAAE;UACZ;QACF,CAAC,CAAC;MACJ,CAAC,CAAC,OAAOkB,KAAU,EAAE;QACnBR,cAAM,CAACQ,KAAK,CAAC;UAAEA,KAAK,EAAEA,KAAK,CAACC;QAAI,CAAC,EAAE,iCAAiC,CAAC;QACrE,OAAOnB,IAAI,CAACoB,gBAAU,CAACC,OAAO,CAACR,iBAAW,CAACS,cAAc,EAAEJ,KAAK,CAACK,OAAO,CAAC,CAAC;MAC5E;IACF;IACA,OAAOvB,IAAI,CAACoB,gBAAU,CAACI,eAAe,EAAE,CAAC;EAC3C,CAAC,CACF;EAEDjC,KAAK,CAACkC,IAAI,CACR,kBAAkB,EAClB,IAAA7B,qBAAS,EAACF,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEG,aAAa,CAAC,EAChC,UAAUC,GAAmB,EAAEC,GAAa,EAAEC,IAAsB,EAAE;IACpE,MAAM;MAAE0B,QAAQ;MAAEC,QAAQ;MAAEC;IAAe,CAAC,GAAG9B,GAAG,CAAC+B,IAAI;IACvD,MAAM;MAAE5B;IAAK,CAAC,GAAGH,GAAG,CAACI,WAAW;IAEhC,IAAI,CAACC,eAAC,CAAC2B,SAAS,CAACH,QAAQ,CAAC,IAAI,CAACxB,eAAC,CAAC4B,OAAO,CAACH,cAAc,CAAC,EAAE;MACxD,OAAO5B,IAAI,CAACoB,gBAAU,CAACC,OAAO,CAACR,iBAAW,CAACmB,QAAQ,EAAEC,oBAAc,CAACC,oBAAoB,CAAC,CAAC;IAC5F;IAEA1C,IAAI,CAAC2C,YAAY,CAAClC,IAAI,EAAEyB,QAAQ,EAAE,OAAOU,GAAG,EAAE7B,IAAiB,KAAK;MAClE,IAAI6B,GAAG,EAAE;QACP,MAAMC,SAAS,GAAGD,GAAG,CAACb,OAAO,GAAGV,iBAAW,CAACyB,YAAY,GAAGzB,iBAAW,CAACS,cAAc;QACrF,OAAOtB,IAAI,CAACoB,gBAAU,CAACC,OAAO,CAACgB,SAAS,EAAED,GAAG,CAACb,OAAO,CAAC,CAAC;MACzD;MAEAzB,GAAG,CAACI,WAAW,GAAGK,IAAI;MAEtB,IAAI,CAACJ,eAAC,CAACoC,UAAU,CAAC9C,OAAO,CAAC+C,SAAS,CAAC,EAAE;QACpC,OAAOxC,IAAI,CACToB,gBAAU,CAACC,OAAO,CAACR,iBAAW,CAAC4B,eAAe,EAAER,oBAAc,CAACS,qBAAqB,CAAC,CACtF;MACH;MAEA,IAAI;QACF,MAAMvD,KAAK,GAAG,MAAM,IAAAwD,iBAAW,EAACnD,IAAI,EAAEE,MAAM,EAAEa,IAAI,EAAgBmB,QAAQ,CAAC;QAC3E,IAAI,CAACvC,KAAK,EAAE;UACV,MAAMiC,gBAAU,CAACwB,gBAAgB,EAAE;QACrC;QAEA,MAAMC,GAAG,GAAG,IAAAC,kBAAW,EAAC3D,KAAK,CAAC;QAC9B;QACA,MAAM4D,WAAW,GAAG,IAAAC,WAAI,EAAC7D,KAAK,EAAE,CAAC,CAAC;QAClC,MAAMC,OAAO,GAAG,IAAIC,IAAI,EAAE,CAAC4D,OAAO,EAAE;;QAEpC;AACV;AACA;AACA;AACA;QACU,MAAMT,SAAgB,GAAG;UACvBjC,IAAI,EAAEN,IAAI;UACVd,KAAK,EAAE4D,WAAW;UAClBF,GAAG;UACHK,IAAI,EAAEtB,cAAc;UACpBD,QAAQ;UACRvC;QACF,CAAC;QAED,MAAMK,OAAO,CAAC+C,SAAS,CAACA,SAAS,CAAC;QAClC9B,cAAM,CAACC,KAAK,CAAC;UAAEkC,GAAG;UAAE5C;QAAK,CAAC,EAAE,2CAA2C,CAAC;QACxEF,GAAG,CAACoD,GAAG,CAACC,aAAO,CAACC,aAAa,EAAE,oBAAoB,CAAC;QACpD,OAAOrD,IAAI,CACTd,cAAc,CAAC;UACbC,KAAK;UACLoB,IAAI,EAAEN,IAAI;UACV4C,GAAG,EAAEL,SAAS,CAACK,GAAG;UAClBK,IAAI,EAAEtB,cAAc;UACpBD,QAAQ;UACRvC,OAAO,EAAEoD,SAAS,CAACpD;QACrB,CAAC,CAAC,CACH;MACH,CAAC,CAAC,OAAO8B,KAAU,EAAE;QACnBR,cAAM,CAACQ,KAAK,CAAC;UAAEA,KAAK,EAAEA,KAAK,CAACC;QAAI,CAAC,EAAE,qCAAqC,CAAC;QACzE,OAAOnB,IAAI,CAACoB,gBAAU,CAACwB,gBAAgB,CAAC1B,KAAK,CAACK,OAAO,CAAC,CAAC;MACzD;IACF,CAAC,CAAC;EACJ,CAAC,CACF;EAEDhC,KAAK,CAAC+D,MAAM,CACV,kCAAkC,EAClC,IAAA1D,qBAAS,EAACF,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEG,aAAa,CAAC,EAChC,OAAOC,GAAmB,EAAEC,GAAa,EAAEC,IAAsB,KAAK;IACpE,MAAM;MACJuD,MAAM,EAAE;QAAEC;MAAS;IACrB,CAAC,GAAG1D,GAAG;IACP,MAAM;MAAEG;IAAK,CAAC,GAAGH,GAAG,CAACI,WAAW;IAEhC,IAAIC,eAAC,CAACC,KAAK,CAACH,IAAI,CAAC,KAAK,KAAK,EAAE;MAC3BS,cAAM,CAACC,KAAK,CAAC;QAAEV;MAAK,CAAC,EAAE,sCAAsC,CAAC;MAC9D,IAAI;QACF,MAAMR,OAAO,CAACgE,WAAW,CAACxD,IAAI,EAAEuD,QAAQ,CAAC;QACzC9C,cAAM,CAACgD,IAAI,CAAC;UAAEF,QAAQ;UAAEvD;QAAK,CAAC,EAAE,mDAAmD,CAAC;QACpF,OAAOD,IAAI,CAAC,CAAC,CAAC,CAAC;MACjB,CAAC,CAAC,OAAOkB,KAAU,EAAE;QACnBR,cAAM,CAACQ,KAAK,CAAC;UAAEA,KAAK,EAAEA,KAAK,CAACC;QAAI,CAAC,EAAE,qCAAqC,CAAC;QACzE,OAAOnB,IAAI,CAACoB,gBAAU,CAACC,OAAO,CAACR,iBAAW,CAACS,cAAc,EAAEJ,KAAK,CAACK,OAAO,CAAC,CAAC;MAC5E;IACF;IACA,OAAOvB,IAAI,CAACoB,gBAAU,CAACI,eAAe,EAAE,CAAC;EAC3C,CAAC,CACF;AACH"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdaccio/api",
3
- "version": "6.0.0-6-next.42",
3
+ "version": "6.0.0-6-next.43",
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.38",
34
- "@verdaccio/config": "6.0.0-6-next.59",
35
- "@verdaccio/core": "6.0.0-6-next.59",
36
- "@verdaccio/logger": "6.0.0-6-next.27",
37
- "@verdaccio/middleware": "6.0.0-6-next.38",
38
- "@verdaccio/store": "6.0.0-6-next.39",
39
- "@verdaccio/utils": "6.0.0-6-next.27",
33
+ "@verdaccio/auth": "6.0.0-6-next.39",
34
+ "@verdaccio/config": "6.0.0-6-next.60",
35
+ "@verdaccio/core": "6.0.0-6-next.60",
36
+ "@verdaccio/logger": "6.0.0-6-next.28",
37
+ "@verdaccio/middleware": "6.0.0-6-next.39",
38
+ "@verdaccio/store": "6.0.0-6-next.40",
39
+ "@verdaccio/utils": "6.0.0-6-next.28",
40
40
  "abortcontroller-polyfill": "1.7.5",
41
41
  "cookies": "0.8.0",
42
42
  "debug": "4.3.4",
@@ -48,8 +48,8 @@
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/node": "16.18.10",
51
- "@verdaccio/server": "6.0.0-6-next.48",
52
- "@verdaccio/types": "11.0.0-6-next.19",
51
+ "@verdaccio/server": "6.0.0-6-next.49",
52
+ "@verdaccio/types": "11.0.0-6-next.20",
53
53
  "@verdaccio/test-helper": "2.0.0-6-next.7",
54
54
  "supertest": "6.3.3",
55
55
  "nock": "13.2.9",
package/src/user.ts CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  validatioUtils,
14
14
  } from '@verdaccio/core';
15
15
  import { logger } from '@verdaccio/logger';
16
+ import { rateLimit } from '@verdaccio/middleware';
16
17
  import { Config, RemoteUser } from '@verdaccio/types';
17
18
  import { getAuthenticatedMessage, mask } from '@verdaccio/utils';
18
19
 
@@ -23,6 +24,7 @@ const debug = buildDebug('verdaccio:api:user');
23
24
  export default function (route: Router, auth: Auth, config: Config): void {
24
25
  route.get(
25
26
  '/-/user/:org_couchdb_user',
27
+ rateLimit(config?.userRateLimit),
26
28
  function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
27
29
  debug('verifying user');
28
30
  const message = getAuthenticatedMessage(req.remote_user.name);
@@ -53,6 +55,7 @@ export default function (route: Router, auth: Auth, config: Config): void {
53
55
  */
54
56
  route.put(
55
57
  '/-/user/:org_couchdb_user/:_rev?/:revision?',
58
+ rateLimit(config?.userRateLimit),
56
59
  function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
57
60
  const { name, password } = req.body;
58
61
  debug('login or adduser');
package/src/v1/profile.ts CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  errorUtils,
11
11
  validatioUtils,
12
12
  } from '@verdaccio/core';
13
+ import { rateLimit } from '@verdaccio/middleware';
13
14
  import { Config } from '@verdaccio/types';
14
15
 
15
16
  import { $NextFunctionVer, $RequestExtend } from '../../types/custom';
@@ -41,6 +42,7 @@ export default function (route: Router, auth: Auth, config: Config): void {
41
42
 
42
43
  route.get(
43
44
  '/-/npm/v1/user',
45
+ rateLimit(config?.userRateLimit),
44
46
  function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
45
47
  if (_.isNil(req.remote_user.name) === false) {
46
48
  return next(buildProfile(req.remote_user.name));
@@ -55,6 +57,7 @@ export default function (route: Router, auth: Auth, config: Config): void {
55
57
 
56
58
  route.post(
57
59
  '/-/npm/v1/user',
60
+ rateLimit(config?.userRateLimit),
58
61
  function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
59
62
  if (_.isNil(req.remote_user.name)) {
60
63
  res.status(HTTP_STATUS.UNAUTHORIZED);
package/src/v1/token.ts CHANGED
@@ -5,6 +5,7 @@ import { getApiToken } from '@verdaccio/auth';
5
5
  import { Auth } from '@verdaccio/auth';
6
6
  import { HEADERS, HTTP_STATUS, SUPPORT_ERRORS, errorUtils } from '@verdaccio/core';
7
7
  import { logger } from '@verdaccio/logger';
8
+ import { rateLimit } from '@verdaccio/middleware';
8
9
  import { Storage } from '@verdaccio/store';
9
10
  import { Config, RemoteUser, Token } from '@verdaccio/types';
10
11
  import { mask, stringToMD5 } from '@verdaccio/utils';
@@ -26,6 +27,7 @@ function normalizeToken(token: Token): NormalizeToken {
26
27
  export default function (route: Router, auth: Auth, storage: Storage, config: Config): void {
27
28
  route.get(
28
29
  '/-/npm/v1/tokens',
30
+ rateLimit(config?.userRateLimit),
29
31
  async function (req: $RequestExtend, res: Response, next: $NextFunctionVer) {
30
32
  const { name } = req.remote_user;
31
33
 
@@ -53,6 +55,7 @@ export default function (route: Router, auth: Auth, storage: Storage, config: Co
53
55
 
54
56
  route.post(
55
57
  '/-/npm/v1/tokens',
58
+ rateLimit(config?.userRateLimit),
56
59
  function (req: $RequestExtend, res: Response, next: $NextFunctionVer) {
57
60
  const { password, readonly, cidr_whitelist } = req.body;
58
61
  const { name } = req.remote_user;
@@ -123,6 +126,7 @@ export default function (route: Router, auth: Auth, storage: Storage, config: Co
123
126
 
124
127
  route.delete(
125
128
  '/-/npm/v1/tokens/token/:tokenKey',
129
+ rateLimit(config?.userRateLimit),
126
130
  async (req: $RequestExtend, res: Response, next: $NextFunctionVer) => {
127
131
  const {
128
132
  params: { tokenKey },