@verdaccio/api 8.1.0-next-8.15 → 8.1.0-next-8.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.js CHANGED
@@ -14,6 +14,7 @@ var _publish = _interopRequireDefault(require("./publish"));
14
14
  var _search = _interopRequireDefault(require("./search"));
15
15
  var _stars = _interopRequireDefault(require("./stars"));
16
16
  var _user = _interopRequireDefault(require("./user"));
17
+ var _login = _interopRequireDefault(require("./v1/login"));
17
18
  var _profile = _interopRequireDefault(require("./v1/profile"));
18
19
  var _search2 = _interopRequireDefault(require("./v1/search"));
19
20
  var _token = _interopRequireDefault(require("./v1/token"));
@@ -65,6 +66,9 @@ function _default(config, auth, storage, logger) {
65
66
  (0, _search2.default)(app, auth, storage, logger);
66
67
  (0, _token.default)(app, auth, storage, config, logger);
67
68
  (0, _package.default)(app, auth, storage, logger);
69
+ if (config.flags?.webLogin) {
70
+ (0, _login.default)(app, auth, storage, config, logger);
71
+ }
68
72
  return app;
69
73
  }
70
74
  function hasBodyParser(app) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_debug","_interopRequireDefault","require","_express","_middleware","_distTags","_package","_ping","_publish","_search","_stars","_user","_profile","_search2","_token","_whoami","e","__esModule","default","debug","buildDebug","_default","config","auth","storage","logger","app","express","Router","param","validatePackage","validateName","match","use","apiJWTmiddleware","hasBodyParser","json","strict","limit","max_body_size","antiLoop","makeURLrelative","encodeScopePackage","whoami","profile","search","user","distTags","publish","ping","stars","v1Search","token","pkg","stack","some","middleware","handle","name"],"sources":["../src/index.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport express, { Router } from 'express';\n\nimport { Auth } from '@verdaccio/auth';\nimport {\n antiLoop,\n encodeScopePackage,\n makeURLrelative,\n match,\n validateName,\n validatePackage,\n} from '@verdaccio/middleware';\nimport { Storage } from '@verdaccio/store';\nimport { Config, Logger } from '@verdaccio/types';\n\nimport distTags from './dist-tags';\nimport pkg from './package';\nimport ping from './ping';\nimport publish from './publish';\nimport search from './search';\nimport stars from './stars';\nimport user from './user';\nimport profile from './v1/profile';\nimport v1Search from './v1/search';\nimport token from './v1/token';\nimport whoami from './whoami';\n\nconst debug = buildDebug('verdaccio:api');\n\nexport default function (config: Config, auth: Auth, storage: Storage, logger: Logger): Router {\n /* eslint new-cap:off */\n const app = express.Router();\n /* eslint new-cap:off */\n\n // validate all of these params as a package name\n // this might be too harsh, so ask if it causes trouble\n app.param('package', validatePackage);\n app.param('filename', validateName);\n app.param('tag', validateName);\n app.param('version', validateName);\n app.param('revision', validateName);\n app.param('token', validateName);\n\n // Express route parameter names must be valid JavaScript identifiers, which means\n // they cannot start with a hyphen (-) or contain special characters like dots (.)\n app.param('_rev', match(/^-rev$/));\n app.param('org_couchdb_user', match(/^org\\.couchdb\\.user:/));\n\n app.use(auth.apiJWTmiddleware());\n\n // middleware might have registered a json parser already\n if (hasBodyParser(app)) {\n debug('json parser already registered');\n } else {\n app.use(express.json({ strict: false, limit: config.max_body_size || '10mb' }));\n }\n\n app.use(antiLoop(config));\n app.use(makeURLrelative);\n // encode / in a scoped package name to be matched as a single parameter in routes\n app.use(encodeScopePackage);\n // for \"npm whoami\"\n whoami(app);\n profile(app, auth, config);\n search(app, logger);\n user(app, auth, config, logger);\n distTags(app, auth, storage, logger);\n publish(app, auth, storage, logger);\n ping(app);\n stars(app, storage);\n v1Search(app, auth, storage, logger);\n token(app, auth, storage, config, logger);\n pkg(app, auth, storage, logger);\n return app;\n}\n\nfunction hasBodyParser(app: Router): boolean {\n const stack = app.stack || [];\n return stack.some((middleware) => {\n return middleware.handle?.name === 'jsonParser' || middleware.name === 'jsonParser';\n });\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["_debug","_interopRequireDefault","require","_express","_middleware","_distTags","_package","_ping","_publish","_search","_stars","_user","_login","_profile","_search2","_token","_whoami","e","__esModule","default","debug","buildDebug","_default","config","auth","storage","logger","app","express","Router","param","validatePackage","validateName","match","use","apiJWTmiddleware","hasBodyParser","json","strict","limit","max_body_size","antiLoop","makeURLrelative","encodeScopePackage","whoami","profile","search","user","distTags","publish","ping","stars","v1Search","token","pkg","flags","webLogin","login","stack","some","middleware","handle","name"],"sources":["../src/index.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport express, { Router } from 'express';\n\nimport { Auth } from '@verdaccio/auth';\nimport {\n antiLoop,\n encodeScopePackage,\n makeURLrelative,\n match,\n validateName,\n validatePackage,\n} from '@verdaccio/middleware';\nimport { Storage } from '@verdaccio/store';\nimport { Config, Logger } from '@verdaccio/types';\n\nimport distTags from './dist-tags';\nimport pkg from './package';\nimport ping from './ping';\nimport publish from './publish';\nimport search from './search';\nimport stars from './stars';\nimport user from './user';\nimport login from './v1/login';\nimport profile from './v1/profile';\nimport v1Search from './v1/search';\nimport token from './v1/token';\nimport whoami from './whoami';\n\nconst debug = buildDebug('verdaccio:api');\n\nexport default function (config: Config, auth: Auth, storage: Storage, logger: Logger): Router {\n /* eslint new-cap:off */\n const app = express.Router();\n /* eslint new-cap:off */\n\n // validate all of these params as a package name\n // this might be too harsh, so ask if it causes trouble\n app.param('package', validatePackage);\n app.param('filename', validateName);\n app.param('tag', validateName);\n app.param('version', validateName);\n app.param('revision', validateName);\n app.param('token', validateName);\n\n // Express route parameter names must be valid JavaScript identifiers, which means\n // they cannot start with a hyphen (-) or contain special characters like dots (.)\n app.param('_rev', match(/^-rev$/));\n app.param('org_couchdb_user', match(/^org\\.couchdb\\.user:/));\n\n app.use(auth.apiJWTmiddleware());\n\n // middleware might have registered a json parser already\n if (hasBodyParser(app)) {\n debug('json parser already registered');\n } else {\n app.use(express.json({ strict: false, limit: config.max_body_size || '10mb' }));\n }\n\n app.use(antiLoop(config));\n app.use(makeURLrelative);\n // encode / in a scoped package name to be matched as a single parameter in routes\n app.use(encodeScopePackage);\n // for \"npm whoami\"\n whoami(app);\n profile(app, auth, config);\n search(app, logger);\n user(app, auth, config, logger);\n distTags(app, auth, storage, logger);\n publish(app, auth, storage, logger);\n ping(app);\n stars(app, storage);\n v1Search(app, auth, storage, logger);\n token(app, auth, storage, config, logger);\n pkg(app, auth, storage, logger);\n if (config.flags?.webLogin) {\n login(app, auth, storage, config, logger);\n }\n return app;\n}\n\nfunction hasBodyParser(app: Router): boolean {\n const stack = app.stack || [];\n return stack.some((middleware) => {\n return middleware.handle?.name === 'jsonParser' || middleware.name === 'jsonParser';\n });\n}\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,QAAA,GAAAF,sBAAA,CAAAC,OAAA;AAGA,IAAAE,WAAA,GAAAF,OAAA;AAWA,IAAAG,SAAA,GAAAJ,sBAAA,CAAAC,OAAA;AACA,IAAAI,QAAA,GAAAL,sBAAA,CAAAC,OAAA;AACA,IAAAK,KAAA,GAAAN,sBAAA,CAAAC,OAAA;AACA,IAAAM,QAAA,GAAAP,sBAAA,CAAAC,OAAA;AACA,IAAAO,OAAA,GAAAR,sBAAA,CAAAC,OAAA;AACA,IAAAQ,MAAA,GAAAT,sBAAA,CAAAC,OAAA;AACA,IAAAS,KAAA,GAAAV,sBAAA,CAAAC,OAAA;AACA,IAAAU,MAAA,GAAAX,sBAAA,CAAAC,OAAA;AACA,IAAAW,QAAA,GAAAZ,sBAAA,CAAAC,OAAA;AACA,IAAAY,QAAA,GAAAb,sBAAA,CAAAC,OAAA;AACA,IAAAa,MAAA,GAAAd,sBAAA,CAAAC,OAAA;AACA,IAAAc,OAAA,GAAAf,sBAAA,CAAAC,OAAA;AAA8B,SAAAD,uBAAAgB,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE9B,MAAMG,KAAK,GAAG,IAAAC,cAAU,EAAC,eAAe,CAAC;AAE1B,SAAAC,SAAUC,MAAc,EAAEC,IAAU,EAAEC,OAAgB,EAAEC,MAAc,EAAU;EAC7F;EACA,MAAMC,GAAG,GAAGC,gBAAO,CAACC,MAAM,CAAC,CAAC;EAC5B;;EAEA;EACA;EACAF,GAAG,CAACG,KAAK,CAAC,SAAS,EAAEC,2BAAe,CAAC;EACrCJ,GAAG,CAACG,KAAK,CAAC,UAAU,EAAEE,wBAAY,CAAC;EACnCL,GAAG,CAACG,KAAK,CAAC,KAAK,EAAEE,wBAAY,CAAC;EAC9BL,GAAG,CAACG,KAAK,CAAC,SAAS,EAAEE,wBAAY,CAAC;EAClCL,GAAG,CAACG,KAAK,CAAC,UAAU,EAAEE,wBAAY,CAAC;EACnCL,GAAG,CAACG,KAAK,CAAC,OAAO,EAAEE,wBAAY,CAAC;;EAEhC;EACA;EACAL,GAAG,CAACG,KAAK,CAAC,MAAM,EAAE,IAAAG,iBAAK,EAAC,QAAQ,CAAC,CAAC;EAClCN,GAAG,CAACG,KAAK,CAAC,kBAAkB,EAAE,IAAAG,iBAAK,EAAC,sBAAsB,CAAC,CAAC;EAE5DN,GAAG,CAACO,GAAG,CAACV,IAAI,CAACW,gBAAgB,CAAC,CAAC,CAAC;;EAEhC;EACA,IAAIC,aAAa,CAACT,GAAG,CAAC,EAAE;IACtBP,KAAK,CAAC,gCAAgC,CAAC;EACzC,CAAC,MAAM;IACLO,GAAG,CAACO,GAAG,CAACN,gBAAO,CAACS,IAAI,CAAC;MAAEC,MAAM,EAAE,KAAK;MAAEC,KAAK,EAAEhB,MAAM,CAACiB,aAAa,IAAI;IAAO,CAAC,CAAC,CAAC;EACjF;EAEAb,GAAG,CAACO,GAAG,CAAC,IAAAO,oBAAQ,EAAClB,MAAM,CAAC,CAAC;EACzBI,GAAG,CAACO,GAAG,CAACQ,2BAAe,CAAC;EACxB;EACAf,GAAG,CAACO,GAAG,CAACS,8BAAkB,CAAC;EAC3B;EACA,IAAAC,eAAM,EAACjB,GAAG,CAAC;EACX,IAAAkB,gBAAO,EAAClB,GAAG,EAAEH,IAAI,EAAED,MAAM,CAAC;EAC1B,IAAAuB,eAAM,EAACnB,GAAG,EAAED,MAAM,CAAC;EACnB,IAAAqB,aAAI,EAACpB,GAAG,EAAEH,IAAI,EAAED,MAAM,EAAEG,MAAM,CAAC;EAC/B,IAAAsB,iBAAQ,EAACrB,GAAG,EAAEH,IAAI,EAAEC,OAAO,EAAEC,MAAM,CAAC;EACpC,IAAAuB,gBAAO,EAACtB,GAAG,EAAEH,IAAI,EAAEC,OAAO,EAAEC,MAAM,CAAC;EACnC,IAAAwB,aAAI,EAACvB,GAAG,CAAC;EACT,IAAAwB,cAAK,EAACxB,GAAG,EAAEF,OAAO,CAAC;EACnB,IAAA2B,gBAAQ,EAACzB,GAAG,EAAEH,IAAI,EAAEC,OAAO,EAAEC,MAAM,CAAC;EACpC,IAAA2B,cAAK,EAAC1B,GAAG,EAAEH,IAAI,EAAEC,OAAO,EAAEF,MAAM,EAAEG,MAAM,CAAC;EACzC,IAAA4B,gBAAG,EAAC3B,GAAG,EAAEH,IAAI,EAAEC,OAAO,EAAEC,MAAM,CAAC;EAC/B,IAAIH,MAAM,CAACgC,KAAK,EAAEC,QAAQ,EAAE;IAC1B,IAAAC,cAAK,EAAC9B,GAAG,EAAEH,IAAI,EAAEC,OAAO,EAAEF,MAAM,EAAEG,MAAM,CAAC;EAC3C;EACA,OAAOC,GAAG;AACZ;AAEA,SAASS,aAAaA,CAACT,GAAW,EAAW;EAC3C,MAAM+B,KAAK,GAAG/B,GAAG,CAAC+B,KAAK,IAAI,EAAE;EAC7B,OAAOA,KAAK,CAACC,IAAI,CAAEC,UAAU,IAAK;IAChC,OAAOA,UAAU,CAACC,MAAM,EAAEC,IAAI,KAAK,YAAY,IAAIF,UAAU,CAACE,IAAI,KAAK,YAAY;EACrF,CAAC,CAAC;AACJ","ignoreList":[]}
package/build/user.js CHANGED
@@ -9,7 +9,6 @@ var _auth = require("@verdaccio/auth");
9
9
  var _config = require("@verdaccio/config");
10
10
  var _core = require("@verdaccio/core");
11
11
  var _middleware = require("@verdaccio/middleware");
12
- var _utils = require("@verdaccio/utils");
13
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
13
  const debug = (0, _debug.default)('verdaccio:api:user');
15
14
  function _default(route, auth, config, logger) {
@@ -23,7 +22,7 @@ function _default(route, auth, config, logger) {
23
22
  });
24
23
  }
25
24
  const username = req.params.org_couchdb_user.split(':')[1];
26
- const message = (0, _utils.getAuthenticatedMessage)(req.remote_user.name);
25
+ const message = _core.authUtils.getAuthenticatedMessage(req.remote_user.name);
27
26
  debug('user authenticated message %o', message);
28
27
  res.status(_core.HTTP_STATUS.OK);
29
28
  next({
@@ -80,7 +79,7 @@ function _default(route, auth, config, logger) {
80
79
  }
81
80
  res.status(_core.HTTP_STATUS.CREATED);
82
81
  res.set(_core.HEADERS.CACHE_CONTROL, 'no-cache, no-store');
83
- const message = (0, _utils.getAuthenticatedMessage)(req.remote_user.name);
82
+ const message = _core.authUtils.getAuthenticatedMessage(req.remote_user.name);
84
83
  debug('login: created user message %o', message);
85
84
  return next({
86
85
  ok: message,
@@ -89,7 +88,7 @@ function _default(route, auth, config, logger) {
89
88
  });
90
89
  } else {
91
90
  debug('adduser: %o', name);
92
- if (_core.validationUtils.validatePassword(password, config?.serverSettings?.passwordValidationRegex) === false) {
91
+ if (_core.validationUtils.validatePassword(password, config?.server?.passwordValidationRegex) === false) {
93
92
  debug('adduser: invalid password');
94
93
  // eslint-disable-next-line new-cap
95
94
  return next(_core.errorUtils.getCode(_core.HTTP_STATUS.BAD_REQUEST, _core.API_ERROR.PASSWORD_SHORT));
@@ -107,7 +106,7 @@ function _default(route, auth, config, logger) {
107
106
  }
108
107
  const token = name && password ? await (0, _auth.getApiToken)(auth, config, user, password) : undefined;
109
108
  if (token) {
110
- debug('adduser: new token %o', (0, _utils.mask)(token, 4));
109
+ debug('adduser: new token %o', _core.cryptoUtils.mask(token, 4));
111
110
  }
112
111
  if (!token) {
113
112
  return next(_core.errorUtils.getUnauthorized());
package/build/user.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"user.js","names":["_debug","_interopRequireDefault","require","_auth","_config","_core","_middleware","_utils","e","__esModule","default","debug","buildDebug","_default","route","auth","config","logger","get","USER_API_ENDPOINTS","get_user","rateLimit","userRateLimit","req","res","next","remote_user","name","status","HTTP_STATUS","OK","ok","username","params","org_couchdb_user","split","message","getAuthenticatedMessage","email","put","add_user","password","body","remoteName","validationUtils","validateUserName","errorUtils","getBadRequest","API_ERROR","USERNAME_MISMATCH","authenticate","callbackAuthenticate","err","user","trace","getCode","UNAUTHORIZED","BAD_USERNAME_PASSWORD","restoredRemoteUser","createRemoteUser","groups","token","getApiToken","getUnauthorized","CREATED","set","HEADERS","CACHE_CONTROL","validatePassword","serverSettings","passwordValidationRegex","BAD_REQUEST","PASSWORD_SHORT","INTERNAL_ERROR","getConflict","undefined","mask","delete","user_token","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 validationUtils,\n} from '@verdaccio/core';\nimport { USER_API_ENDPOINTS, rateLimit } from '@verdaccio/middleware';\nimport { Logger } from '@verdaccio/types';\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, logger: Logger): void {\n route.get(\n USER_API_ENDPOINTS.get_user,\n rateLimit(config?.userRateLimit),\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n debug('verifying user');\n\n if (\n !req.remote_user ||\n typeof req.remote_user.name !== 'string' ||\n req.remote_user.name === ''\n ) {\n debug('user not logged in');\n res.status(HTTP_STATUS.OK);\n return next({ ok: false });\n }\n\n const username = req.params.org_couchdb_user.split(':')[1];\n const message = getAuthenticatedMessage(req.remote_user.name);\n debug('user authenticated message %o', message);\n res.status(HTTP_STATUS.OK);\n next({\n // 'npm owner' requires user info\n // TODO: we don't have the email\n name: username,\n email: '',\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_API_ENDPOINTS.add_user,\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 (!validationUtils.validateUserName(req.params.org_couchdb_user, name)) {\n return next(errorUtils.getBadRequest(API_ERROR.USERNAME_MISMATCH));\n }\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 debug('adduser: %o', name);\n if (\n validationUtils.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_API_ENDPOINTS.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":";;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AAGA,IAAAC,KAAA,GAAAD,OAAA;AAEA,IAAAE,OAAA,GAAAF,OAAA;AACA,IAAAG,KAAA,GAAAH,OAAA;AAQA,IAAAI,WAAA,GAAAJ,OAAA;AAGA,IAAAK,MAAA,GAAAL,OAAA;AAAiE,SAAAD,uBAAAO,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAIjE,MAAMG,KAAK,GAAG,IAAAC,cAAU,EAAC,oBAAoB,CAAC;AAE/B,SAAAC,SAAUC,KAAa,EAAEC,IAAU,EAAEC,MAAc,EAAEC,MAAc,EAAQ;EACxFH,KAAK,CAACI,GAAG,CACPC,8BAAkB,CAACC,QAAQ,EAC3B,IAAAC,qBAAS,EAACL,MAAM,EAAEM,aAAa,CAAC,EAChC,UAAUC,GAAmB,EAAEC,GAAa,EAAEC,IAAsB,EAAQ;IAC1Ed,KAAK,CAAC,gBAAgB,CAAC;IAEvB,IACE,CAACY,GAAG,CAACG,WAAW,IAChB,OAAOH,GAAG,CAACG,WAAW,CAACC,IAAI,KAAK,QAAQ,IACxCJ,GAAG,CAACG,WAAW,CAACC,IAAI,KAAK,EAAE,EAC3B;MACAhB,KAAK,CAAC,oBAAoB,CAAC;MAC3Ba,GAAG,CAACI,MAAM,CAACC,iBAAW,CAACC,EAAE,CAAC;MAC1B,OAAOL,IAAI,CAAC;QAAEM,EAAE,EAAE;MAAM,CAAC,CAAC;IAC5B;IAEA,MAAMC,QAAQ,GAAGT,GAAG,CAACU,MAAM,CAACC,gBAAgB,CAACC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1D,MAAMC,OAAO,GAAG,IAAAC,8BAAuB,EAACd,GAAG,CAACG,WAAW,CAACC,IAAI,CAAC;IAC7DhB,KAAK,CAAC,+BAA+B,EAAEyB,OAAO,CAAC;IAC/CZ,GAAG,CAACI,MAAM,CAACC,iBAAW,CAACC,EAAE,CAAC;IAC1BL,IAAI,CAAC;MACH;MACA;MACAE,IAAI,EAAEK,QAAQ;MACdM,KAAK,EAAE,EAAE;MACTP,EAAE,EAAEK;IACN,CAAC,CAAC;EACJ,CACF,CAAC;;EAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEtB,KAAK,CAACyB,GAAG,CACPpB,8BAAkB,CAACqB,QAAQ,EAC3B,IAAAnB,qBAAS,EAACL,MAAM,EAAEM,aAAa,CAAC,EAChC,UAAUC,GAAmB,EAAEC,GAAa,EAAEC,IAAsB,EAAQ;IAC1E,MAAM;MAAEE,IAAI;MAAEc;IAAS,CAAC,GAAGlB,GAAG,CAACmB,IAAI;IACnC/B,KAAK,CAAC,kBAAkB,CAAC;IACzB,MAAMgC,UAAU,GAAGpB,GAAG,EAAEG,WAAW,EAAEC,IAAI;IAEzC,IAAI,CAACiB,qBAAe,CAACC,gBAAgB,CAACtB,GAAG,CAACU,MAAM,CAACC,gBAAgB,EAAEP,IAAI,CAAC,EAAE;MACxE,OAAOF,IAAI,CAACqB,gBAAU,CAACC,aAAa,CAACC,eAAS,CAACC,iBAAiB,CAAC,CAAC;IACpE;IAEA,IAAI,OAAON,UAAU,KAAK,WAAW,IAAI,OAAOhB,IAAI,KAAK,QAAQ,IAAIgB,UAAU,KAAKhB,IAAI,EAAE;MACxFhB,KAAK,CAAC,gCAAgC,CAAC;MACvCI,IAAI,CAACmC,YAAY,CACfvB,IAAI,EACJc,QAAQ,EACR,eAAeU,oBAAoBA,CAACC,GAAG,EAAEC,IAAI,EAAiB;QAC5D,IAAID,GAAG,EAAE;UACPnC,MAAM,CAACqC,KAAK,CACV;YAAE3B,IAAI;YAAEyB;UAAI,CAAC,EACb,mEACF,CAAC;UACD,OAAO3B,IAAI,CACTqB,gBAAU,CAACS,OAAO,CAAC1B,iBAAW,CAAC2B,YAAY,EAAER,eAAS,CAACS,qBAAqB,CAC9E,CAAC;QACH;QAEA,MAAMC,kBAA8B,GAAG,IAAAC,wBAAgB,EAAChC,IAAI,EAAE0B,IAAI,EAAEO,MAAM,IAAI,EAAE,CAAC;QACjF,MAAMC,KAAK,GAAG,MAAM,IAAAC,iBAAW,EAAC/C,IAAI,EAAEC,MAAM,EAAE0C,kBAAkB,EAAEjB,QAAQ,CAAC;QAC3E9B,KAAK,CAAC,kBAAkB,CAAC;QACzB,IAAI,CAACkD,KAAK,EAAE;UACV,OAAOpC,IAAI,CAACqB,gBAAU,CAACiB,eAAe,CAAC,CAAC,CAAC;QAC3C;QAEAvC,GAAG,CAACI,MAAM,CAACC,iBAAW,CAACmC,OAAO,CAAC;QAC/BxC,GAAG,CAACyC,GAAG,CAACC,aAAO,CAACC,aAAa,EAAE,oBAAoB,CAAC;QAEpD,MAAM/B,OAAO,GAAG,IAAAC,8BAAuB,EAACd,GAAG,CAACG,WAAW,CAACC,IAAI,CAAC;QAC7DhB,KAAK,CAAC,gCAAgC,EAAEyB,OAAO,CAAC;QAEhD,OAAOX,IAAI,CAAC;UACVM,EAAE,EAAEK,OAAO;UACXyB;QACF,CAAC,CAAC;MACJ,CACF,CAAC;IACH,CAAC,MAAM;MACLlD,KAAK,CAAC,aAAa,EAAEgB,IAAI,CAAC;MAC1B,IACEiB,qBAAe,CAACwB,gBAAgB,CAC9B3B,QAAQ,EACRzB,MAAM,EAAEqD,cAAc,EAAEC,uBAC1B,CAAC,KAAK,KAAK,EACX;QACA3D,KAAK,CAAC,2BAA2B,CAAC;QAClC;QACA,OAAOc,IAAI,CAACqB,gBAAU,CAACS,OAAO,CAAC1B,iBAAW,CAAC0C,WAAW,EAAEvB,eAAS,CAACwB,cAAc,CAAC,CAAC;MACpF;MAEAzD,IAAI,CAACyB,QAAQ,CAACb,IAAI,EAAEc,QAAQ,EAAE,gBAAgBW,GAAG,EAAEC,IAAI,EAAiB;QACtE,IAAID,GAAG,EAAE;UACP,IAAIA,GAAG,CAACxB,MAAM,IAAIC,iBAAW,CAAC0C,WAAW,IAAInB,GAAG,CAACxB,MAAM,GAAGC,iBAAW,CAAC4C,cAAc,EAAE;YACpF9D,KAAK,CAAC,+BAA+B,CAAC;YACtC;YACA;YACA;YACA,OAAOc,IAAI,CACTqB,gBAAU,CAACS,OAAO,CAACH,GAAG,CAACxB,MAAM,EAAEwB,GAAG,CAAChB,OAAO,CAAC,IAAIU,gBAAU,CAAC4B,WAAW,CAACtB,GAAG,CAAChB,OAAO,CACnF,CAAC;UACH;UACA,OAAOX,IAAI,CAAC2B,GAAG,CAAC;QAClB;QAEA,MAAMS,KAAK,GACTlC,IAAI,IAAIc,QAAQ,GACZ,MAAM,IAAAqB,iBAAW,EAAC/C,IAAI,EAAEC,MAAM,EAAEqC,IAAI,EAAgBZ,QAAQ,CAAC,GAC7DkC,SAAS;QACf,IAAId,KAAK,EAAE;UACTlD,KAAK,CAAC,uBAAuB,EAAE,IAAAiE,WAAI,EAACf,KAAK,EAAY,CAAC,CAAC,CAAC;QAC1D;QACA,IAAI,CAACA,KAAK,EAAE;UACV,OAAOpC,IAAI,CAACqB,gBAAU,CAACiB,eAAe,CAAC,CAAC,CAAC;QAC3C;QAEAxC,GAAG,CAACG,WAAW,GAAG2B,IAAI;QACtB7B,GAAG,CAACI,MAAM,CAACC,iBAAW,CAACmC,OAAO,CAAC;QAC/BxC,GAAG,CAACyC,GAAG,CAACC,aAAO,CAACC,aAAa,EAAE,oBAAoB,CAAC;QACpDxD,KAAK,CAAC,gCAAgC,CAAC;QACvC,OAAOc,IAAI,CAAC;UACVM,EAAE,EAAE,SAASR,GAAG,CAACmB,IAAI,CAACf,IAAI,WAAW;UACrCkC;QACF,CAAC,CAAC;MACJ,CAAC,CAAC;IACJ;EACF,CACF,CAAC;EAED/C,KAAK,CAAC+D,MAAM,CACV1D,8BAAkB,CAAC2D,UAAU,EAC7B,UAAUvD,GAAmB,EAAEC,GAAa,EAAEC,IAAsB,EAAQ;IAC1ED,GAAG,CAACI,MAAM,CAACC,iBAAW,CAACC,EAAE,CAAC;IAC1BL,IAAI,CAAC;MACHM,EAAE,EAAEgD,iBAAW,CAACC;IAClB,CAAC,CAAC;EACJ,CACF,CAAC;AACH","ignoreList":[]}
1
+ {"version":3,"file":"user.js","names":["_debug","_interopRequireDefault","require","_auth","_config","_core","_middleware","e","__esModule","default","debug","buildDebug","_default","route","auth","config","logger","get","USER_API_ENDPOINTS","get_user","rateLimit","userRateLimit","req","res","next","remote_user","name","status","HTTP_STATUS","OK","ok","username","params","org_couchdb_user","split","message","authUtils","getAuthenticatedMessage","email","put","add_user","password","body","remoteName","validationUtils","validateUserName","errorUtils","getBadRequest","API_ERROR","USERNAME_MISMATCH","authenticate","callbackAuthenticate","err","user","trace","getCode","UNAUTHORIZED","BAD_USERNAME_PASSWORD","restoredRemoteUser","createRemoteUser","groups","token","getApiToken","getUnauthorized","CREATED","set","HEADERS","CACHE_CONTROL","validatePassword","server","passwordValidationRegex","BAD_REQUEST","PASSWORD_SHORT","INTERNAL_ERROR","getConflict","undefined","cryptoUtils","mask","delete","user_token","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 authUtils,\n cryptoUtils,\n errorUtils,\n validationUtils,\n} from '@verdaccio/core';\nimport { USER_API_ENDPOINTS, rateLimit } from '@verdaccio/middleware';\nimport { Logger } from '@verdaccio/types';\nimport { Config, RemoteUser } from '@verdaccio/types';\n\nimport { $NextFunctionVer, $RequestExtend } from '../types/custom';\n\nconst debug = buildDebug('verdaccio:api:user');\n\nexport default function (route: Router, auth: Auth, config: Config, logger: Logger): void {\n route.get(\n USER_API_ENDPOINTS.get_user,\n rateLimit(config?.userRateLimit),\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n debug('verifying user');\n\n if (\n !req.remote_user ||\n typeof req.remote_user.name !== 'string' ||\n req.remote_user.name === ''\n ) {\n debug('user not logged in');\n res.status(HTTP_STATUS.OK);\n return next({ ok: false });\n }\n\n const username = req.params.org_couchdb_user.split(':')[1];\n const message = authUtils.getAuthenticatedMessage(req.remote_user.name);\n debug('user authenticated message %o', message);\n res.status(HTTP_STATUS.OK);\n next({\n // 'npm owner' requires user info\n // TODO: we don't have the email\n name: username,\n email: '',\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_API_ENDPOINTS.add_user,\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 (!validationUtils.validateUserName(req.params.org_couchdb_user, name)) {\n return next(errorUtils.getBadRequest(API_ERROR.USERNAME_MISMATCH));\n }\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 = authUtils.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 debug('adduser: %o', name);\n if (\n validationUtils.validatePassword(password, config?.server?.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', cryptoUtils.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_API_ENDPOINTS.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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","ignoreList":[]}
@@ -0,0 +1,5 @@
1
+ import { Router } from 'express';
2
+ import { Auth } from '@verdaccio/auth';
3
+ import { Storage } from '@verdaccio/store';
4
+ import { Config, Logger } from '@verdaccio/types';
5
+ export default function (route: Router, auth: Auth, storage: Storage, config: Config, logger: Logger): void;
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = _default;
7
+ var _debug = _interopRequireDefault(require("debug"));
8
+ var _nodeCrypto = require("node:crypto");
9
+ var _auth = require("@verdaccio/auth");
10
+ var _config = require("@verdaccio/config");
11
+ var _core = require("@verdaccio/core");
12
+ var _middleware = require("@verdaccio/middleware");
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
+ const debug = (0, _debug.default)('verdaccio:api:login');
15
+ const WEB_LOGIN_SESSION_ID = 'web-login-sessionId';
16
+
17
+ // https://github.com/npm/npm-profile/blob/main/lib/index.js
18
+ function _default(route, auth, storage, config, logger) {
19
+ route.post(_middleware.LOGIN_API_ENDPOINTS.login, (0, _middleware.rateLimit)(config?.userRateLimit), async function (req, res) {
20
+ // create new login session (without token)
21
+ const sessionId = (0, _nodeCrypto.randomUUID)();
22
+ debug('creating login session %o', sessionId);
23
+ await storage.saveToken({
24
+ user: sessionId,
25
+ token: '',
26
+ key: WEB_LOGIN_SESSION_ID,
27
+ readonly: false,
28
+ created: new Date().getTime()
29
+ });
30
+ res.status(_core.HTTP_STATUS.OK);
31
+
32
+ // Assuming Web UI is running on the same address as API
33
+ const protocol = req.protocol;
34
+ const host = req.hostname;
35
+ const port = req.socket.localPort;
36
+ const loginUrl = `${protocol}://${host}:${port}/-/web/login?next=${_middleware.LOGIN_API_ENDPOINTS.login_cli}/${sessionId}`;
37
+ const doneUrl = `${protocol}://${host}:${port}${_middleware.LOGIN_API_ENDPOINTS.login_done}/${sessionId}`;
38
+ debug('loginUrl: %o', loginUrl);
39
+ debug('doneUrl: %o', doneUrl);
40
+ res.json({
41
+ loginUrl,
42
+ doneUrl
43
+ });
44
+ });
45
+ route.get(_middleware.LOGIN_API_ENDPOINTS.login_done_session, (0, _middleware.rateLimit)(config?.userRateLimit), async function (req, res, next) {
46
+ debug('polling login session %o', req.params.sessionId);
47
+ if (!req.params.sessionId) {
48
+ return next(_core.errorUtils.getCode(_core.HTTP_STATUS.BAD_REQUEST, _core.API_ERROR.SESSION_ID_REQUIRED));
49
+ }
50
+ const sessionId = req.params.sessionId;
51
+ if (sessionId.length !== 36) {
52
+ return next(_core.errorUtils.getCode(_core.HTTP_STATUS.BAD_REQUEST, _core.API_ERROR.SESSION_ID_INVALID));
53
+ }
54
+ try {
55
+ const tokens = await storage.readTokens({
56
+ user: sessionId
57
+ });
58
+ if (tokens && tokens.length === 1 && tokens[0].key === WEB_LOGIN_SESSION_ID) {
59
+ if (tokens[0].token.length === 0) {
60
+ debug('waiting for authentication');
61
+ // Poll again after short delay
62
+ // TODO: make this configurable (default 5 seconds)
63
+ res.status(_core.HTTP_STATUS.ACCEPTED);
64
+ res.set(_core.HEADERS.RETRY_AFTER, '5');
65
+ res.json({});
66
+ } else {
67
+ // session token can only be used once
68
+ await storage.deleteToken(sessionId, tokens[0].key);
69
+
70
+ // Check if token has expired
71
+ // TODO: make this configurable (default 2 minutes)
72
+ const tokenCreatedDate = new Date(tokens[0].created);
73
+ const minutesAgo = new Date(Date.now() - 2 * 60 * 1000);
74
+ if (tokenCreatedDate < minutesAgo) {
75
+ debug('session token expired');
76
+ return next(_core.errorUtils.getUnauthorized(_core.API_ERROR.SESSION_TOKEN_EXPIRED));
77
+ }
78
+ debug('session token is valid, login successful');
79
+ res.status(_core.HTTP_STATUS.OK);
80
+ res.json({
81
+ token: tokens[0].token
82
+ });
83
+ }
84
+ } else {
85
+ return next(_core.errorUtils.getCode(_core.HTTP_STATUS.BAD_REQUEST, _core.API_ERROR.SESSION_ID_INVALID));
86
+ }
87
+ } catch (error) {
88
+ logger.error({
89
+ error: error.msg
90
+ }, 'token list has failed: @{error}');
91
+ return next(_core.errorUtils.getCode(_core.HTTP_STATUS.INTERNAL_ERROR, error.message));
92
+ }
93
+ });
94
+ route.post(_middleware.LOGIN_API_ENDPOINTS.login_cli_session, (0, _middleware.rateLimit)(config?.userRateLimit), async function (req, res, next) {
95
+ const {
96
+ username,
97
+ password
98
+ } = req.body;
99
+ debug('authenticating login session %o for user %o', req.params.sessionId, username);
100
+ if (!req.params.sessionId) {
101
+ return next(_core.errorUtils.getCode(_core.HTTP_STATUS.BAD_REQUEST, _core.API_ERROR.SESSION_ID_REQUIRED));
102
+ }
103
+ const sessionId = req.params.sessionId;
104
+ if (sessionId.length !== 36) {
105
+ return next(_core.errorUtils.getCode(_core.HTTP_STATUS.BAD_REQUEST, _core.API_ERROR.SESSION_ID_INVALID));
106
+ }
107
+ auth.authenticate(username, password, async function callbackAuthenticate(err, user) {
108
+ if (err) {
109
+ logger.trace({
110
+ username,
111
+ err
112
+ }, 'authenticating for user @{username} failed. Error: @{err.message}');
113
+ return next(_core.errorUtils.getCode(_core.HTTP_STATUS.UNAUTHORIZED, err.message));
114
+ }
115
+ const remoteUser = (0, _config.createRemoteUser)(username, user?.groups || []);
116
+ const token = await (0, _auth.getApiToken)(auth, config, remoteUser, password);
117
+ if (!token) {
118
+ return next(_core.errorUtils.getUnauthorized());
119
+ }
120
+
121
+ // Replace login session with token (to be picked up by the "done" endpoint)
122
+ await storage.deleteToken(sessionId, WEB_LOGIN_SESSION_ID);
123
+ await storage.saveToken({
124
+ user: sessionId,
125
+ token,
126
+ key: WEB_LOGIN_SESSION_ID,
127
+ readonly: false,
128
+ created: new Date().getTime()
129
+ });
130
+ const message = _core.authUtils.getAuthenticatedMessage(remoteUser.name ?? '');
131
+ res.status(_core.HTTP_STATUS.CREATED);
132
+ res.set(_core.HEADERS.CACHE_CONTROL, 'no-cache, no-store');
133
+ res.json({
134
+ ok: message,
135
+ token
136
+ });
137
+ });
138
+ });
139
+ }
140
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","names":["_debug","_interopRequireDefault","require","_nodeCrypto","_auth","_config","_core","_middleware","e","__esModule","default","debug","buildDebug","WEB_LOGIN_SESSION_ID","_default","route","auth","storage","config","logger","post","LOGIN_API_ENDPOINTS","login","rateLimit","userRateLimit","req","res","sessionId","randomUUID","saveToken","user","token","key","readonly","created","Date","getTime","status","HTTP_STATUS","OK","protocol","host","hostname","port","socket","localPort","loginUrl","login_cli","doneUrl","login_done","json","get","login_done_session","next","params","errorUtils","getCode","BAD_REQUEST","API_ERROR","SESSION_ID_REQUIRED","length","SESSION_ID_INVALID","tokens","readTokens","ACCEPTED","set","HEADERS","RETRY_AFTER","deleteToken","tokenCreatedDate","minutesAgo","now","getUnauthorized","SESSION_TOKEN_EXPIRED","error","msg","INTERNAL_ERROR","message","login_cli_session","username","password","body","authenticate","callbackAuthenticate","err","trace","UNAUTHORIZED","remoteUser","createRemoteUser","groups","getApiToken","authUtils","getAuthenticatedMessage","name","CREATED","CACHE_CONTROL","ok"],"sources":["../../src/v1/login.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Response, Router } from 'express';\nimport { randomUUID } from 'node:crypto';\n\nimport { Auth, getApiToken } from '@verdaccio/auth';\nimport { createRemoteUser } from '@verdaccio/config';\nimport { API_ERROR, HEADERS, HTTP_STATUS, authUtils, errorUtils } from '@verdaccio/core';\nimport { LOGIN_API_ENDPOINTS, rateLimit } from '@verdaccio/middleware';\nimport { Storage } from '@verdaccio/store';\nimport { Config, Logger } from '@verdaccio/types';\n\nimport { $NextFunctionVer, $RequestExtend } from '../../types/custom';\n\nconst debug = buildDebug('verdaccio:api:login');\n\nconst WEB_LOGIN_SESSION_ID = 'web-login-sessionId';\n\n// https://github.com/npm/npm-profile/blob/main/lib/index.js\nexport default function (\n route: Router,\n auth: Auth,\n storage: Storage,\n config: Config,\n logger: Logger\n): void {\n route.post(\n LOGIN_API_ENDPOINTS.login,\n rateLimit(config?.userRateLimit),\n async function (req: $RequestExtend, res: Response): Promise<void> {\n // create new login session (without token)\n const sessionId = randomUUID();\n debug('creating login session %o', sessionId);\n\n await storage.saveToken({\n user: sessionId,\n token: '',\n key: WEB_LOGIN_SESSION_ID,\n readonly: false,\n created: new Date().getTime(),\n });\n\n res.status(HTTP_STATUS.OK);\n\n // Assuming Web UI is running on the same address as API\n const protocol = req.protocol;\n const host = req.hostname;\n const port = req.socket.localPort;\n\n const loginUrl = `${protocol}://${host}:${port}/-/web/login?next=${LOGIN_API_ENDPOINTS.login_cli}/${sessionId}`;\n const doneUrl = `${protocol}://${host}:${port}${LOGIN_API_ENDPOINTS.login_done}/${sessionId}`;\n debug('loginUrl: %o', loginUrl);\n debug('doneUrl: %o', doneUrl);\n\n res.json({\n loginUrl,\n doneUrl,\n });\n }\n );\n\n route.get(\n LOGIN_API_ENDPOINTS.login_done_session,\n rateLimit(config?.userRateLimit),\n async function (req: $RequestExtend, res: Response, next: $NextFunctionVer): Promise<void> {\n debug('polling login session %o', req.params.sessionId);\n\n if (!req.params.sessionId) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.SESSION_ID_REQUIRED));\n }\n const sessionId = req.params.sessionId;\n if (sessionId.length !== 36) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.SESSION_ID_INVALID));\n }\n\n try {\n const tokens = await storage.readTokens({ user: sessionId });\n\n if (tokens && tokens.length === 1 && tokens[0].key === WEB_LOGIN_SESSION_ID) {\n if (tokens[0].token.length === 0) {\n debug('waiting for authentication');\n // Poll again after short delay\n // TODO: make this configurable (default 5 seconds)\n res.status(HTTP_STATUS.ACCEPTED);\n res.set(HEADERS.RETRY_AFTER, '5');\n res.json({});\n } else {\n // session token can only be used once\n await storage.deleteToken(sessionId, tokens[0].key);\n\n // Check if token has expired\n // TODO: make this configurable (default 2 minutes)\n const tokenCreatedDate = new Date(tokens[0].created);\n const minutesAgo = new Date(Date.now() - 2 * 60 * 1000);\n if (tokenCreatedDate < minutesAgo) {\n debug('session token expired');\n return next(errorUtils.getUnauthorized(API_ERROR.SESSION_TOKEN_EXPIRED));\n }\n\n debug('session token is valid, login successful');\n\n res.status(HTTP_STATUS.OK);\n res.json({ token: tokens[0].token });\n }\n } else {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.SESSION_ID_INVALID));\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 );\n\n route.post(\n LOGIN_API_ENDPOINTS.login_cli_session,\n rateLimit(config?.userRateLimit),\n async function (req: $RequestExtend, res: Response, next: $NextFunctionVer): Promise<void> {\n const { username, password } = req.body;\n debug('authenticating login session %o for user %o', req.params.sessionId, username);\n\n if (!req.params.sessionId) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.SESSION_ID_REQUIRED));\n }\n const sessionId = req.params.sessionId;\n if (sessionId.length !== 36) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.SESSION_ID_INVALID));\n }\n\n auth.authenticate(\n username,\n password,\n async function callbackAuthenticate(err, user): Promise<void> {\n if (err) {\n logger.trace(\n { username, err },\n 'authenticating for user @{username} failed. Error: @{err.message}'\n );\n return next(errorUtils.getCode(HTTP_STATUS.UNAUTHORIZED, err.message));\n }\n\n const remoteUser = createRemoteUser(username, user?.groups || []);\n const token = await getApiToken(auth, config, remoteUser, password);\n\n if (!token) {\n return next(errorUtils.getUnauthorized());\n }\n\n // Replace login session with token (to be picked up by the \"done\" endpoint)\n await storage.deleteToken(sessionId, WEB_LOGIN_SESSION_ID);\n await storage.saveToken({\n user: sessionId,\n token,\n key: WEB_LOGIN_SESSION_ID,\n readonly: false,\n created: new Date().getTime(),\n });\n\n const message = authUtils.getAuthenticatedMessage(remoteUser.name ?? '');\n\n res.status(HTTP_STATUS.CREATED);\n res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');\n res.json({ ok: message, token });\n }\n );\n }\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -45,7 +45,7 @@ function _default(route, auth, config) {
45
45
  name
46
46
  } = req.remote_user;
47
47
  if (_lodash.default.isNil(password) === false) {
48
- if (_core.validationUtils.validatePassword(password.new, config?.serverSettings?.passwordValidationRegex) === false) {
48
+ if (_core.validationUtils.validatePassword(password.new, config?.server?.passwordValidationRegex) === false) {
49
49
  /* eslint new-cap:off */
50
50
  return next(_core.errorUtils.getCode(_core.HTTP_STATUS.UNAUTHORIZED, _core.API_ERROR.PASSWORD_SHORT));
51
51
  /* eslint new-cap:off */
@@ -1 +1 @@
1
- {"version":3,"file":"profile.js","names":["_lodash","_interopRequireDefault","require","_core","_middleware","e","__esModule","default","_default","route","auth","config","buildProfile","name","tfa","email","email_verified","created","updated","cidr_whitelist","fullname","get","PROFILE_API_ENDPOINTS","get_profile","rateLimit","userRateLimit","req","res","next","_","isNil","remote_user","status","HTTP_STATUS","UNAUTHORIZED","message","API_ERROR","MUST_BE_LOGGED","post","password","body","validationUtils","validatePassword","new","serverSettings","passwordValidationRegex","errorUtils","getCode","PASSWORD_SHORT","isEmpty","old","getBadRequest","changePassword","err","isUpdated","isNull","getForbidden","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 validationUtils,\n} from '@verdaccio/core';\nimport { PROFILE_API_ENDPOINTS } from '@verdaccio/middleware';\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 PROFILE_API_ENDPOINTS.get_profile,\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 PROFILE_API_ENDPOINTS.get_profile,\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 validationUtils.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 if (_.isEmpty(password.old)) {\n return next(errorUtils.getBadRequest('old password is required'));\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(errorUtils.getForbidden(err.message));\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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","ignoreList":[]}
1
+ {"version":3,"file":"profile.js","names":["_lodash","_interopRequireDefault","require","_core","_middleware","e","__esModule","default","_default","route","auth","config","buildProfile","name","tfa","email","email_verified","created","updated","cidr_whitelist","fullname","get","PROFILE_API_ENDPOINTS","get_profile","rateLimit","userRateLimit","req","res","next","_","isNil","remote_user","status","HTTP_STATUS","UNAUTHORIZED","message","API_ERROR","MUST_BE_LOGGED","post","password","body","validationUtils","validatePassword","new","server","passwordValidationRegex","errorUtils","getCode","PASSWORD_SHORT","isEmpty","old","getBadRequest","changePassword","err","isUpdated","isNull","getForbidden","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 validationUtils,\n} from '@verdaccio/core';\nimport { PROFILE_API_ENDPOINTS } from '@verdaccio/middleware';\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 PROFILE_API_ENDPOINTS.get_profile,\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 PROFILE_API_ENDPOINTS.get_profile,\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 validationUtils.validatePassword(\n password.new,\n config?.server?.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 if (_.isEmpty(password.old)) {\n return next(errorUtils.getBadRequest('old password is required'));\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(errorUtils.getForbidden(err.message));\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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","ignoreList":[]}
@@ -1,9 +1,9 @@
1
1
  import { Router } from 'express';
2
2
  import { Auth } from '@verdaccio/auth';
3
3
  import { Storage } from '@verdaccio/store';
4
- import { Config, Token } from '@verdaccio/types';
5
- import { Logger } from '@verdaccio/types';
4
+ import { Config, Logger, Token } from '@verdaccio/types';
6
5
  export type NormalizeToken = Token & {
6
+ cidr_whitelist: string[];
7
7
  created: string;
8
8
  };
9
9
  export default function (route: Router, auth: Auth, storage: Storage, config: Config, logger: Logger): void;
package/build/v1/token.js CHANGED
@@ -8,11 +8,12 @@ var _lodash = _interopRequireDefault(require("lodash"));
8
8
  var _auth = require("@verdaccio/auth");
9
9
  var _core = require("@verdaccio/core");
10
10
  var _middleware = require("@verdaccio/middleware");
11
- var _utils = require("@verdaccio/utils");
12
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ // npm expects "cidr_whitelist" for token list
13
13
  function normalizeToken(token) {
14
14
  return {
15
15
  ...token,
16
+ cidr_whitelist: token.cidr || [],
16
17
  created: new Date(token.created).toISOString()
17
18
  };
18
19
  }
@@ -74,9 +75,9 @@ function _default(route, auth, storage, config, logger) {
74
75
  if (!token) {
75
76
  throw _core.errorUtils.getInternalError();
76
77
  }
77
- const key = (0, _utils.stringToMD5)(token);
78
+ const key = _core.cryptoUtils.stringToMD5(token);
78
79
  // TODO: use a utility here
79
- const maskedToken = (0, _utils.mask)(token, 5);
80
+ const maskedToken = _core.cryptoUtils.mask(token, 5);
80
81
  const created = new Date().getTime();
81
82
 
82
83
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"token.js","names":["_lodash","_interopRequireDefault","require","_auth","_core","_middleware","_utils","e","__esModule","default","normalizeToken","token","created","Date","toISOString","_default","route","auth","storage","config","logger","get","TOKEN_API_ENDPOINTS","get_tokens","rateLimit","userRateLimit","req","res","next","name","remote_user","_","isNil","tokens","readTokens","user","totalTokens","length","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","delete_token","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 { rateLimit } from '@verdaccio/middleware';\nimport { TOKEN_API_ENDPOINTS } from '@verdaccio/middleware';\nimport { Storage } from '@verdaccio/store';\nimport { Config, RemoteUser, Token } from '@verdaccio/types';\nimport { Logger } 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 (\n route: Router,\n auth: Auth,\n storage: Storage,\n config: Config,\n logger: Logger\n): void {\n route.get(\n TOKEN_API_ENDPOINTS.get_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 TOKEN_API_ENDPOINTS.get_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 TOKEN_API_ENDPOINTS.delete_token,\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":"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","ignoreList":[]}
1
+ {"version":3,"file":"token.js","names":["_lodash","_interopRequireDefault","require","_auth","_core","_middleware","e","__esModule","default","normalizeToken","token","cidr_whitelist","cidr","created","Date","toISOString","_default","route","auth","storage","config","logger","get","TOKEN_API_ENDPOINTS","get_tokens","rateLimit","userRateLimit","req","res","next","name","remote_user","_","isNil","tokens","readTokens","user","totalTokens","length","debug","status","HTTP_STATUS","OK","objects","map","urls","error","msg","errorUtils","getCode","INTERNAL_ERROR","message","getUnauthorized","post","password","readonly","body","isBoolean","isArray","BAD_DATA","SUPPORT_ERRORS","PARAMETERS_NOT_VALID","authenticate","err","errorCode","UNAUTHORIZED","isFunction","saveToken","NOT_IMPLEMENTED","STORAGE_NOT_IMPLEMENT","getApiToken","getInternalError","key","cryptoUtils","stringToMD5","maskedToken","mask","getTime","set","HEADERS","CACHE_CONTROL","delete","delete_token","params","tokenKey","deleteToken","info"],"sources":["../../src/v1/token.ts"],"sourcesContent":["import { Response, Router } from 'express';\nimport _ from 'lodash';\n\nimport { Auth, getApiToken } from '@verdaccio/auth';\nimport { HEADERS, HTTP_STATUS, SUPPORT_ERRORS, cryptoUtils, errorUtils } from '@verdaccio/core';\nimport { TOKEN_API_ENDPOINTS, rateLimit } from '@verdaccio/middleware';\nimport { Storage } from '@verdaccio/store';\nimport { Config, Logger, RemoteUser, Token } from '@verdaccio/types';\n\nimport { $NextFunctionVer, $RequestExtend } from '../../types/custom';\n\nexport type NormalizeToken = Token & {\n cidr_whitelist: string[];\n created: string;\n};\n\n// npm expects \"cidr_whitelist\" for token list\nfunction normalizeToken(token: Token): NormalizeToken {\n return {\n ...token,\n cidr_whitelist: token.cidr || [],\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 (\n route: Router,\n auth: Auth,\n storage: Storage,\n config: Config,\n logger: Logger\n): void {\n route.get(\n TOKEN_API_ENDPOINTS.get_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 TOKEN_API_ENDPOINTS.get_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 = cryptoUtils.stringToMD5(token);\n // TODO: use a utility here\n const maskedToken = cryptoUtils.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 TOKEN_API_ENDPOINTS.delete_token,\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":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdaccio/api",
3
- "version": "8.1.0-next-8.15",
3
+ "version": "8.1.0-next-8.16",
4
4
  "description": "Verdaccio Registry API",
5
5
  "main": "./build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -33,13 +33,12 @@
33
33
  },
34
34
  "license": "MIT",
35
35
  "dependencies": {
36
- "@verdaccio/auth": "8.0.0-next-8.15",
37
- "@verdaccio/config": "8.0.0-next-8.15",
38
- "@verdaccio/core": "8.0.0-next-8.15",
39
- "@verdaccio/logger": "8.0.0-next-8.15",
40
- "@verdaccio/middleware": "8.0.0-next-8.15",
41
- "@verdaccio/store": "8.0.0-next-8.15",
42
- "@verdaccio/utils": "8.1.0-next-8.15",
36
+ "@verdaccio/auth": "8.0.0-next-8.16",
37
+ "@verdaccio/config": "8.0.0-next-8.16",
38
+ "@verdaccio/core": "8.0.0-next-8.16",
39
+ "@verdaccio/logger": "8.0.0-next-8.16",
40
+ "@verdaccio/middleware": "8.0.0-next-8.16",
41
+ "@verdaccio/store": "8.0.0-next-8.16",
43
42
  "abortcontroller-polyfill": "1.7.8",
44
43
  "body-parser": "1.20.3",
45
44
  "cookies": "0.9.1",
@@ -50,8 +49,8 @@
50
49
  "semver": "7.7.1"
51
50
  },
52
51
  "devDependencies": {
53
- "@verdaccio/test-helper": "4.0.0-next-8.4",
54
- "@verdaccio/types": "13.0.0-next-8.5",
52
+ "@verdaccio/test-helper": "4.0.0-next-8.5",
53
+ "@verdaccio/types": "13.0.0-next-8.6",
55
54
  "mockdate": "3.0.5",
56
55
  "supertest": "7.0.0"
57
56
  },