@verdaccio/api 6.0.0-6-next.12 → 6.0.0-6-next.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/build/dist-tags.d.ts +2 -2
  3. package/build/dist-tags.js +8 -8
  4. package/build/dist-tags.js.map +1 -1
  5. package/build/index.d.ts +2 -2
  6. package/build/index.js +12 -13
  7. package/build/index.js.map +1 -1
  8. package/build/package.d.ts +2 -2
  9. package/build/package.js +6 -6
  10. package/build/package.js.map +1 -1
  11. package/build/publish.d.ts +7 -7
  12. package/build/publish.js +24 -22
  13. package/build/publish.js.map +1 -1
  14. package/build/search.d.ts +1 -1
  15. package/build/search.js +9 -102
  16. package/build/search.js.map +1 -1
  17. package/build/star.d.ts +2 -2
  18. package/build/star.js +6 -5
  19. package/build/star.js.map +1 -1
  20. package/build/stars.d.ts +2 -2
  21. package/build/stars.js +3 -3
  22. package/build/stars.js.map +1 -1
  23. package/build/user.js +12 -12
  24. package/build/user.js.map +1 -1
  25. package/build/v1/profile.js +10 -10
  26. package/build/v1/profile.js.map +1 -1
  27. package/build/v1/search.d.ts +9 -1
  28. package/build/v1/search.js +71 -88
  29. package/build/v1/search.js.map +1 -1
  30. package/build/v1/token.d.ts +2 -2
  31. package/build/v1/token.js +12 -12
  32. package/build/v1/token.js.map +1 -1
  33. package/build/whoami.js +0 -1
  34. package/build/whoami.js.map +1 -1
  35. package/package.json +16 -13
  36. package/src/dist-tags.ts +10 -10
  37. package/src/index.ts +12 -11
  38. package/src/package.ts +5 -10
  39. package/src/publish.ts +28 -19
  40. package/src/search.ts +9 -100
  41. package/src/star.ts +4 -3
  42. package/src/stars.ts +3 -3
  43. package/src/user.ts +7 -7
  44. package/src/v1/profile.ts +7 -7
  45. package/src/v1/search.ts +64 -89
  46. package/src/v1/token.ts +13 -18
  47. package/src/whoami.ts +0 -1
  48. package/test/integration/_helper.ts +3 -2
  49. package/test/integration/package.spec.ts +3 -3
  50. package/test/integration/ping.spec.ts +1 -1
  51. package/test/integration/publish.spec.ts +3 -8
  52. package/test/integration/user.spec.ts +6 -8
  53. package/test/integration/whoami.spec.ts +1 -1
  54. package/test/unit/publish.spec.ts +11 -15
  55. package/tsconfig.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/v1/profile.ts"],"names":["route","auth","buildProfile","name","tfa","email","email_verified","created","updated","cidr_whitelist","fullname","get","req","res","next","_","isNil","remote_user","status","HTTP_STATUS","UNAUTHORIZED","message","API_ERROR","MUST_BE_LOGGED","post","password","body","new","ErrorCode","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"],"mappings":"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","sourcesContent":["import _ from 'lodash';\nimport { Response, Router } from 'express';\n\nimport { API_ERROR, APP_ERROR, HTTP_STATUS, SUPPORT_ERRORS } from '@verdaccio/commons-api';\nimport { ErrorCode, validatePassword } from '@verdaccio/utils';\nimport { IAuth } from '@verdaccio/auth';\nimport { $RequestExtend, $NextFunctionVer } from '../../types/custom';\n\nexport interface Profile {\n tfa: boolean;\n name: string;\n email: string;\n email_verified: boolean;\n created: string;\n updated: string;\n cidr_whitelist: string[] | null;\n fullname: string;\n}\n\nexport default function (route: Router, auth: IAuth): void {\n function buildProfile(name: string): Profile {\n return {\n tfa: false,\n name,\n email: '',\n email_verified: false,\n created: '',\n updated: '',\n cidr_whitelist: null,\n fullname: '',\n };\n }\n\n route.get(\n '/-/npm/v1/user',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n if (_.isNil(req.remote_user.name) === false) {\n return next(buildProfile(req.remote_user.name));\n }\n\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n );\n\n route.post(\n '/-/npm/v1/user',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n if (_.isNil(req.remote_user.name)) {\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n\n const { password, tfa } = req.body;\n const { name } = req.remote_user;\n\n if (_.isNil(password) === false) {\n if (validatePassword(password.new) === false) {\n /* eslint new-cap:off */\n return next(ErrorCode.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 ErrorCode.getCode(err.status, err.message) || ErrorCode.getConflict(err.message)\n );\n }\n\n if (isUpdated) {\n return next(buildProfile(req.remote_user.name));\n }\n return next(ErrorCode.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));\n }\n );\n } else if (_.isNil(tfa) === false) {\n return next(\n ErrorCode.getCode(HTTP_STATUS.SERVICE_UNAVAILABLE, SUPPORT_ERRORS.TFA_DISABLED)\n );\n } else {\n return next(ErrorCode.getCode(HTTP_STATUS.INTERNAL_ERROR, APP_ERROR.PROFILE_ERROR));\n }\n }\n );\n}\n"],"file":"profile.js"}
1
+ {"version":3,"sources":["../../src/v1/profile.ts"],"names":["route","auth","buildProfile","name","tfa","email","email_verified","created","updated","cidr_whitelist","fullname","get","req","res","next","_","isNil","remote_user","status","HTTP_STATUS","UNAUTHORIZED","message","API_ERROR","MUST_BE_LOGGED","post","password","body","new","errorUtils","getCode","PASSWORD_SHORT","changePassword","old","err","isUpdated","isNull","getConflict","getInternalError","INTERNAL_SERVER_ERROR","SERVICE_UNAVAILABLE","SUPPORT_ERRORS","TFA_DISABLED","INTERNAL_ERROR","APP_ERROR","PROFILE_ERROR"],"mappings":"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","sourcesContent":["import _ from 'lodash';\nimport { Response, Router } from 'express';\n\nimport { API_ERROR, APP_ERROR, HTTP_STATUS, SUPPORT_ERRORS, errorUtils } from '@verdaccio/core';\nimport { validatePassword } from '@verdaccio/utils';\nimport { IAuth } from '@verdaccio/auth';\nimport { $RequestExtend, $NextFunctionVer } from '../../types/custom';\n\nexport interface Profile {\n tfa: boolean;\n name: string;\n email: string;\n email_verified: boolean;\n created: string;\n updated: string;\n cidr_whitelist: string[] | null;\n fullname: string;\n}\n\nexport default function (route: Router, auth: IAuth): void {\n function buildProfile(name: string): Profile {\n return {\n tfa: false,\n name,\n email: '',\n email_verified: false,\n created: '',\n updated: '',\n cidr_whitelist: null,\n fullname: '',\n };\n }\n\n route.get(\n '/-/npm/v1/user',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n if (_.isNil(req.remote_user.name) === false) {\n return next(buildProfile(req.remote_user.name));\n }\n\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n );\n\n route.post(\n '/-/npm/v1/user',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n if (_.isNil(req.remote_user.name)) {\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n\n const { password, tfa } = req.body;\n const { name } = req.remote_user;\n\n if (_.isNil(password) === false) {\n if (validatePassword(password.new) === false) {\n /* eslint new-cap:off */\n return next(errorUtils.getCode(HTTP_STATUS.UNAUTHORIZED, API_ERROR.PASSWORD_SHORT()));\n /* eslint new-cap:off */\n }\n\n auth.changePassword(\n name,\n password.old,\n password.new,\n (err, isUpdated): $NextFunctionVer => {\n if (_.isNull(err) === false) {\n return next(\n errorUtils.getCode(err.status, err.message) || errorUtils.getConflict(err.message)\n );\n }\n\n if (isUpdated) {\n return next(buildProfile(req.remote_user.name));\n }\n return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));\n }\n );\n } else if (_.isNil(tfa) === false) {\n return next(\n errorUtils.getCode(HTTP_STATUS.SERVICE_UNAVAILABLE, SUPPORT_ERRORS.TFA_DISABLED)\n );\n } else {\n return next(errorUtils.getCode(HTTP_STATUS.INTERNAL_ERROR, APP_ERROR.PROFILE_ERROR));\n }\n }\n );\n}\n"],"file":"profile.js"}
@@ -1 +1,9 @@
1
- export default function (route: any, auth: any, storage: any): void;
1
+ import { IAuth } from '@verdaccio/auth';
2
+ import { Storage } from '@verdaccio/store';
3
+ /**
4
+ * Endpoint for npm search v1
5
+ * Empty value
6
+ * - {"objects":[],"total":0,"time":"Sun Jul 25 2021 14:09:11 GMT+0000 (Coordinated Universal Time)"}
7
+ * req: 'GET /-/v1/search?text=react&size=20&frpom=0&quality=0.65&popularity=0.98&maintenance=0.5'
8
+ */
9
+ export default function (route: any, auth: IAuth, storage: Storage): void;
@@ -5,109 +5,92 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = _default;
7
7
 
8
- var _semver = _interopRequireDefault(require("semver"));
8
+ var _lodash = _interopRequireDefault(require("lodash"));
9
9
 
10
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
-
12
- function compileTextSearch(textSearch) {
13
- const personMatch = (person, search) => {
14
- if (typeof person === 'string') {
15
- return person.includes(search);
16
- }
17
-
18
- if (typeof person === 'object') {
19
- for (const field of Object.values(person)) {
20
- if (typeof field === 'string' && field.includes(search)) {
21
- return true;
22
- }
23
- }
24
- }
10
+ var _debug = _interopRequireDefault(require("debug"));
25
11
 
26
- return false;
27
- };
12
+ var _logger = require("@verdaccio/logger");
28
13
 
29
- const matcher = function (q) {
30
- const match = q.match(/author:(.*)/);
31
-
32
- if (match !== null) {
33
- return pkg => personMatch(pkg.author, match[1]);
34
- } // TODO: maintainer, keywords, not/is unstable insecure, boost-exact
35
- // TODO implement some scoring system for freetext
14
+ var _core = require("@verdaccio/core");
36
15
 
16
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
37
17
 
38
- return pkg => {
39
- return ['name', 'displayName', 'description'].map(k => pkg[k]).filter(x => x !== undefined).some(txt => txt.includes(q));
40
- };
41
- };
42
-
43
- const textMatchers = (textSearch || '').split(' ').map(matcher);
44
- return pkg => textMatchers.every(m => m(pkg));
45
- }
18
+ const debug = (0, _debug.default)('verdaccio:api:search');
19
+ /**
20
+ * Endpoint for npm search v1
21
+ * Empty value
22
+ * - {"objects":[],"total":0,"time":"Sun Jul 25 2021 14:09:11 GMT+0000 (Coordinated Universal Time)"}
23
+ * req: 'GET /-/v1/search?text=react&size=20&frpom=0&quality=0.65&popularity=0.98&maintenance=0.5'
24
+ */
46
25
 
47
26
  function _default(route, auth, storage) {
48
- route.get('/-/v1/search', (req, res) => {
49
- // TODO: implement proper result scoring weighted by quality, popularity and
50
- // maintenance query parameters
51
- let [text, size, from] = ['text', 'size', 'from'
52
- /* , 'quality', 'popularity', 'maintenance' */
53
- ].map(k => req.query[k]);
54
- size = parseInt(size) || 20;
55
- from = parseInt(from) || 0;
56
- const isInteresting = compileTextSearch(text);
57
- const resultStream = storage.search(0, {
58
- req: {
59
- query: {
60
- local: true
27
+ function checkAccess(pkg, auth, remoteUser) {
28
+ return new Promise((resolve, reject) => {
29
+ var _pkg$package;
30
+
31
+ auth.allow_access({
32
+ packageName: pkg === null || pkg === void 0 ? void 0 : (_pkg$package = pkg.package) === null || _pkg$package === void 0 ? void 0 : _pkg$package.name
33
+ }, remoteUser, function (err, allowed) {
34
+ if (err) {
35
+ if (err.status && String(err.status).match(/^4\d\d$/)) {
36
+ // auth plugin returns 4xx user error,
37
+ // that's equivalent of !allowed basically
38
+ allowed = false;
39
+ return resolve(null);
40
+ } else {
41
+ reject(err);
42
+ }
43
+ } else {
44
+ return resolve(allowed ? pkg : null);
61
45
  }
62
- }
46
+ });
63
47
  });
64
- const resultBuf = [];
65
- let completed = false;
48
+ }
49
+
50
+ route.get('/-/v1/search', async (req, res, next) => {
51
+ const {
52
+ query,
53
+ url
54
+ } = req;
55
+ let [size, from] = ['size', 'from'].map(k => query[k]);
56
+ let data;
57
+ const abort = new AbortController();
58
+ req.on('aborted', () => {
59
+ abort.abort();
60
+ });
61
+ size = parseInt(size, 10) || 20;
62
+ from = parseInt(from, 10) || 0;
63
+
64
+ try {
65
+ var _storage$searchManage;
66
+
67
+ data = await ((_storage$searchManage = storage.searchManager) === null || _storage$searchManage === void 0 ? void 0 : _storage$searchManage.search({
68
+ query,
69
+ url,
70
+ abort
71
+ }));
72
+ debug('stream finish');
73
+ const checkAccessPromises = await Promise.all(data.map(pkgItem => {
74
+ return checkAccess(pkgItem, auth, req.remote_user);
75
+ }));
76
+ const final = checkAccessPromises.filter(i => !_lodash.default.isNull(i)).slice(from, size);
77
+
78
+ _logger.logger.debug(`search results ${final === null || final === void 0 ? void 0 : final.length}`);
66
79
 
67
- const sendResponse = () => {
68
- completed = true;
69
- resultStream.destroy();
70
- const final = resultBuf.slice(from, size).map(pkg => {
71
- return {
72
- package: pkg,
73
- flags: {
74
- unstable: Object.keys(pkg.versions).some(v => _semver.default.satisfies(v, '^1.0.0')) ? undefined : true
75
- },
76
- score: {
77
- final: 1,
78
- detail: {
79
- quality: 1,
80
- popularity: 1,
81
- maintenance: 0
82
- }
83
- },
84
- searchScore: 100000
85
- };
86
- });
87
80
  const response = {
88
81
  objects: final,
89
82
  total: final.length,
90
83
  time: new Date().toUTCString()
91
84
  };
92
- res.status(200).json(response);
93
- };
94
-
95
- resultStream.on('data', pkg => {
96
- if (!isInteresting(pkg)) {
97
- return;
98
- }
99
-
100
- resultBuf.push(pkg);
101
-
102
- if (!completed && resultBuf.length >= size + from) {
103
- sendResponse();
104
- }
105
- });
106
- resultStream.on('end', () => {
107
- if (!completed) {
108
- sendResponse();
109
- }
110
- });
85
+ res.status(_core.HTTP_STATUS.OK).json(response);
86
+ } catch (error) {
87
+ _logger.logger.error({
88
+ error
89
+ }, 'search endpoint has failed @{error.message}');
90
+
91
+ next(next);
92
+ return;
93
+ }
111
94
  });
112
95
  }
113
96
  //# sourceMappingURL=search.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/v1/search.ts"],"names":["compileTextSearch","textSearch","personMatch","person","search","includes","field","Object","values","matcher","q","match","pkg","author","map","k","filter","x","undefined","some","txt","textMatchers","split","every","m","route","auth","storage","get","req","res","text","size","from","query","parseInt","isInteresting","resultStream","local","resultBuf","completed","sendResponse","destroy","final","slice","package","flags","unstable","keys","versions","v","semver","satisfies","score","detail","quality","popularity","maintenance","searchScore","response","objects","total","length","time","Date","toUTCString","status","json","on","push"],"mappings":"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","sourcesContent":["import semver from 'semver';\nimport { Package } from '@verdaccio/types';\n\nfunction compileTextSearch(textSearch: string): (pkg: Package) => boolean {\n const personMatch = (person, search) => {\n if (typeof person === 'string') {\n return person.includes(search);\n }\n\n if (typeof person === 'object') {\n for (const field of Object.values(person)) {\n if (typeof field === 'string' && field.includes(search)) {\n return true;\n }\n }\n }\n\n return false;\n };\n const matcher = function (q) {\n const match = q.match(/author:(.*)/);\n if (match !== null) {\n return (pkg) => personMatch(pkg.author, match[1]);\n }\n\n // TODO: maintainer, keywords, not/is unstable insecure, boost-exact\n // TODO implement some scoring system for freetext\n return (pkg) => {\n return ['name', 'displayName', 'description']\n .map((k) => pkg[k])\n .filter((x) => x !== undefined)\n .some((txt) => txt.includes(q));\n };\n };\n\n const textMatchers = (textSearch || '').split(' ').map(matcher);\n return (pkg) => textMatchers.every((m) => m(pkg));\n}\n\nexport default function (route, auth, storage): void {\n route.get('/-/v1/search', (req, res) => {\n // TODO: implement proper result scoring weighted by quality, popularity and\n // maintenance query parameters\n let [text, size, from] = [\n 'text',\n 'size',\n 'from' /* , 'quality', 'popularity', 'maintenance' */,\n ].map((k) => req.query[k]);\n\n size = parseInt(size) || 20;\n from = parseInt(from) || 0;\n\n const isInteresting = compileTextSearch(text);\n\n const resultStream = storage.search(0, { req: { query: { local: true } } });\n const resultBuf = [] as any;\n let completed = false;\n\n const sendResponse = (): void => {\n completed = true;\n resultStream.destroy();\n\n const final = resultBuf.slice(from, size).map((pkg) => {\n return {\n package: pkg,\n flags: {\n unstable: Object.keys(pkg.versions).some((v) => semver.satisfies(v, '^1.0.0'))\n ? undefined\n : true,\n },\n score: {\n final: 1,\n detail: {\n quality: 1,\n popularity: 1,\n maintenance: 0,\n },\n },\n searchScore: 100000,\n };\n });\n const response = {\n objects: final,\n total: final.length,\n time: new Date().toUTCString(),\n };\n\n res.status(200).json(response);\n };\n\n resultStream.on('data', (pkg) => {\n if (!isInteresting(pkg)) {\n return;\n }\n resultBuf.push(pkg);\n if (!completed && resultBuf.length >= size + from) {\n sendResponse();\n }\n });\n resultStream.on('end', () => {\n if (!completed) {\n sendResponse();\n }\n });\n });\n}\n"],"file":"search.js"}
1
+ {"version":3,"sources":["../../src/v1/search.ts"],"names":["debug","route","auth","storage","checkAccess","pkg","remoteUser","Promise","resolve","reject","allow_access","packageName","package","name","err","allowed","status","String","match","get","req","res","next","query","url","size","from","map","k","data","abort","AbortController","on","parseInt","searchManager","search","checkAccessPromises","all","pkgItem","remote_user","final","filter","i","_","isNull","slice","logger","length","response","objects","total","time","Date","toUTCString","HTTP_STATUS","OK","json","error"],"mappings":"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","sourcesContent":["import _ from 'lodash';\nimport buildDebug from 'debug';\nimport { logger } from '@verdaccio/logger';\nimport { IAuth } from '@verdaccio/auth';\nimport { HTTP_STATUS, searchUtils } from '@verdaccio/core';\nimport { Storage } from '@verdaccio/store';\nimport { Package } from '@verdaccio/types';\n\nconst debug = buildDebug('verdaccio:api:search');\n\n/**\n * Endpoint for npm search v1\n * Empty value\n * - {\"objects\":[],\"total\":0,\"time\":\"Sun Jul 25 2021 14:09:11 GMT+0000 (Coordinated Universal Time)\"}\n * req: 'GET /-/v1/search?text=react&size=20&frpom=0&quality=0.65&popularity=0.98&maintenance=0.5'\n */\nexport default function (route, auth: IAuth, storage: Storage): void {\n function checkAccess(pkg: any, auth: any, remoteUser): Promise<Package | null> {\n return new Promise((resolve, reject) => {\n auth.allow_access({ packageName: pkg?.package?.name }, remoteUser, function (err, allowed) {\n if (err) {\n if (err.status && String(err.status).match(/^4\\d\\d$/)) {\n // auth plugin returns 4xx user error,\n // that's equivalent of !allowed basically\n allowed = false;\n return resolve(null);\n } else {\n reject(err);\n }\n } else {\n return resolve(allowed ? pkg : null);\n }\n });\n });\n }\n\n route.get('/-/v1/search', async (req, res, next) => {\n const { query, url } = req;\n let [size, from] = ['size', 'from'].map((k) => query[k]);\n let data;\n const abort = new AbortController();\n\n req.on('aborted', () => {\n abort.abort();\n });\n\n size = parseInt(size, 10) || 20;\n from = parseInt(from, 10) || 0;\n\n try {\n data = await storage.searchManager?.search({\n query,\n url,\n abort,\n });\n debug('stream finish');\n const checkAccessPromises: searchUtils.SearchItemPkg[] = await Promise.all(\n data.map((pkgItem) => {\n return checkAccess(pkgItem, auth, req.remote_user);\n })\n );\n\n const final: searchUtils.SearchItemPkg[] = checkAccessPromises\n .filter((i) => !_.isNull(i))\n .slice(from, size);\n logger.debug(`search results ${final?.length}`);\n\n const response: searchUtils.SearchResults = {\n objects: final,\n total: final.length,\n time: new Date().toUTCString(),\n };\n\n res.status(HTTP_STATUS.OK).json(response);\n } catch (error) {\n logger.error({ error }, 'search endpoint has failed @{error.message}');\n next(next);\n return;\n }\n });\n}\n"],"file":"search.js"}
@@ -1,8 +1,8 @@
1
1
  import { Router } from 'express';
2
2
  import { Config, Token } from '@verdaccio/types';
3
3
  import { IAuth } from '@verdaccio/auth';
4
- import { IStorageHandler } from '@verdaccio/store';
4
+ import { Storage } from '@verdaccio/store';
5
5
  export declare type NormalizeToken = Token & {
6
6
  created: string;
7
7
  };
8
- export default function (route: Router, auth: IAuth, storage: IStorageHandler, config: Config): void;
8
+ export default function (route: Router, auth: IAuth, storage: Storage, config: Config): void;
package/build/v1/token.js CHANGED
@@ -7,7 +7,7 @@ exports.default = _default;
7
7
 
8
8
  var _lodash = _interopRequireDefault(require("lodash"));
9
9
 
10
- var _commonsApi = require("@verdaccio/commons-api");
10
+ var _core = require("@verdaccio/core");
11
11
 
12
12
  var _utils = require("@verdaccio/utils");
13
13
 
@@ -47,7 +47,7 @@ function _default(route, auth, storage, config) {
47
47
  totalTokens
48
48
  }, 'token list retrieved: @{totalTokens}');
49
49
 
50
- res.status(_commonsApi.HTTP_STATUS.OK);
50
+ res.status(_core.HTTP_STATUS.OK);
51
51
  return next({
52
52
  objects: tokens.map(normalizeToken),
53
53
  urls: {
@@ -60,11 +60,11 @@ function _default(route, auth, storage, config) {
60
60
  error: error.msg
61
61
  }, 'token list has failed: @{error}');
62
62
 
63
- return next(_utils.ErrorCode.getCode(_commonsApi.HTTP_STATUS.INTERNAL_ERROR, error.message));
63
+ return next(_core.errorUtils.getCode(_core.HTTP_STATUS.INTERNAL_ERROR, error.message));
64
64
  }
65
65
  }
66
66
 
67
- return next(_utils.ErrorCode.getUnauthorized());
67
+ return next(_core.errorUtils.getUnauthorized());
68
68
  });
69
69
  route.post('/-/npm/v1/tokens', function (req, res, next) {
70
70
  const {
@@ -77,26 +77,26 @@ function _default(route, auth, storage, config) {
77
77
  } = req.remote_user;
78
78
 
79
79
  if (!_lodash.default.isBoolean(readonly) || !_lodash.default.isArray(cidr_whitelist)) {
80
- return next(_utils.ErrorCode.getCode(_commonsApi.HTTP_STATUS.BAD_DATA, _commonsApi.SUPPORT_ERRORS.PARAMETERS_NOT_VALID));
80
+ return next(_core.errorUtils.getCode(_core.HTTP_STATUS.BAD_DATA, _core.SUPPORT_ERRORS.PARAMETERS_NOT_VALID));
81
81
  }
82
82
 
83
83
  auth.authenticate(name, password, async (err, user) => {
84
84
  if (err) {
85
- const errorCode = err.message ? _commonsApi.HTTP_STATUS.UNAUTHORIZED : _commonsApi.HTTP_STATUS.INTERNAL_ERROR;
86
- return next(_utils.ErrorCode.getCode(errorCode, err.message));
85
+ const errorCode = err.message ? _core.HTTP_STATUS.UNAUTHORIZED : _core.HTTP_STATUS.INTERNAL_ERROR;
86
+ return next(_core.errorUtils.getCode(errorCode, err.message));
87
87
  }
88
88
 
89
89
  req.remote_user = user;
90
90
 
91
91
  if (!_lodash.default.isFunction(storage.saveToken)) {
92
- return next(_utils.ErrorCode.getCode(_commonsApi.HTTP_STATUS.NOT_IMPLEMENTED, _commonsApi.SUPPORT_ERRORS.STORAGE_NOT_IMPLEMENT));
92
+ return next(_core.errorUtils.getCode(_core.HTTP_STATUS.NOT_IMPLEMENTED, _core.SUPPORT_ERRORS.STORAGE_NOT_IMPLEMENT));
93
93
  }
94
94
 
95
95
  try {
96
96
  const token = await (0, _auth.getApiToken)(auth, config, user, password);
97
97
 
98
98
  if (!token) {
99
- throw (0, _commonsApi.getInternalError)();
99
+ throw _core.errorUtils.getInternalError();
100
100
  }
101
101
 
102
102
  const key = (0, _utils.stringToMD5)(token); // TODO: use a utility here
@@ -137,7 +137,7 @@ function _default(route, auth, storage, config) {
137
137
  error: error.msg
138
138
  }, 'token creation has failed: @{error}');
139
139
 
140
- return next(_utils.ErrorCode.getCode(_commonsApi.HTTP_STATUS.INTERNAL_ERROR, error.message));
140
+ return next(_core.errorUtils.getInternalError(error.message));
141
141
  }
142
142
  });
143
143
  });
@@ -170,11 +170,11 @@ function _default(route, auth, storage, config) {
170
170
  error: error.msg
171
171
  }, 'token creation has failed: @{error}');
172
172
 
173
- return next(_utils.ErrorCode.getCode(_commonsApi.HTTP_STATUS.INTERNAL_ERROR, error.message));
173
+ return next(_core.errorUtils.getCode(_core.HTTP_STATUS.INTERNAL_ERROR, error.message));
174
174
  }
175
175
  }
176
176
 
177
- return next(_utils.ErrorCode.getUnauthorized());
177
+ return next(_core.errorUtils.getUnauthorized());
178
178
  });
179
179
  }
180
180
  //# sourceMappingURL=token.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/v1/token.ts"],"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","ErrorCode","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","key","maskedToken","getTime","cidr","delete","params","tokenKey","deleteToken","info"],"mappings":"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","sourcesContent":["import _ from 'lodash';\nimport { HTTP_STATUS, SUPPORT_ERRORS, getInternalError } from '@verdaccio/commons-api';\nimport { ErrorCode, stringToMD5, mask } from '@verdaccio/utils';\nimport { getApiToken } from '@verdaccio/auth';\nimport { logger } from '@verdaccio/logger';\nimport { Response, Router } from 'express';\n\nimport { Config, RemoteUser, Token } from '@verdaccio/types';\nimport { IAuth } from '@verdaccio/auth';\nimport { IStorageHandler } from '@verdaccio/store';\nimport { $RequestExtend, $NextFunctionVer } 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: IAuth,\n storage: IStorageHandler,\n config: Config\n): 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(ErrorCode.getCode(HTTP_STATUS.INTERNAL_ERROR, error.message));\n }\n }\n return next(ErrorCode.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(ErrorCode.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(ErrorCode.getCode(errorCode, err.message));\n }\n\n req.remote_user = user;\n\n if (!_.isFunction(storage.saveToken)) {\n return next(\n ErrorCode.getCode(HTTP_STATUS.NOT_IMPLEMENTED, SUPPORT_ERRORS.STORAGE_NOT_IMPLEMENT)\n );\n }\n\n try {\n const token = await getApiToken(auth, config, user, password);\n if (!token) {\n throw getInternalError();\n }\n\n const key = stringToMD5(token);\n // TODO: use a utility here\n const maskedToken = mask(token, 5);\n const created = new Date().getTime();\n\n /**\n * cidr_whitelist: is not being used, we pass it through\n * token: we do not store the real token (it is generated once and retrieved\n * to the user), just a mask of it.\n */\n const saveToken: Token = {\n user: name,\n token: maskedToken,\n key,\n cidr: cidr_whitelist,\n readonly,\n created,\n };\n\n await storage.saveToken(saveToken);\n logger.debug({ key, name }, 'token @{key} was created for user @{name}');\n return next(\n normalizeToken({\n token,\n user: name,\n key: saveToken.key,\n cidr: cidr_whitelist,\n readonly,\n created: saveToken.created,\n })\n );\n } catch (error: any) {\n logger.error({ error: error.msg }, 'token creation has failed: @{error}');\n return next(ErrorCode.getCode(HTTP_STATUS.INTERNAL_ERROR, 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(ErrorCode.getCode(HTTP_STATUS.INTERNAL_ERROR, error.message));\n }\n }\n return next(ErrorCode.getUnauthorized());\n }\n );\n}\n"],"file":"token.js"}
1
+ {"version":3,"sources":["../../src/v1/token.ts"],"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","getInternalError","key","maskedToken","getTime","cidr","delete","params","tokenKey","deleteToken","info"],"mappings":"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","sourcesContent":["import _ from 'lodash';\nimport { errorUtils, HTTP_STATUS, SUPPORT_ERRORS } from '@verdaccio/core';\nimport { stringToMD5, mask } from '@verdaccio/utils';\nimport { getApiToken } from '@verdaccio/auth';\nimport { logger } from '@verdaccio/logger';\nimport { Response, Router } from 'express';\n\nimport { Config, RemoteUser, Token } from '@verdaccio/types';\nimport { IAuth } from '@verdaccio/auth';\nimport { Storage } from '@verdaccio/store';\nimport { $RequestExtend, $NextFunctionVer } from '../../types/custom';\n\nexport type NormalizeToken = Token & {\n created: string;\n};\n\nfunction normalizeToken(token: Token): NormalizeToken {\n return {\n ...token,\n created: new Date(token.created).toISOString(),\n };\n}\n\n// https://github.com/npm/npm-profile/blob/latest/lib/index.js\nexport default function (route: Router, auth: IAuth, storage: Storage, config: Config): void {\n route.get(\n '/-/npm/v1/tokens',\n async function (req: $RequestExtend, res: Response, next: $NextFunctionVer) {\n const { name } = req.remote_user;\n\n if (_.isNil(name) === false) {\n try {\n const tokens = await storage.readTokens({ user: name });\n const totalTokens = tokens.length;\n logger.debug({ totalTokens }, 'token list retrieved: @{totalTokens}');\n\n res.status(HTTP_STATUS.OK);\n return next({\n objects: tokens.map(normalizeToken),\n urls: {\n next: '', // TODO: pagination?\n },\n });\n } catch (error: any) {\n logger.error({ error: error.msg }, 'token list has failed: @{error}');\n return next(errorUtils.getCode(HTTP_STATUS.INTERNAL_ERROR, error.message));\n }\n }\n return next(errorUtils.getUnauthorized());\n }\n );\n\n route.post(\n '/-/npm/v1/tokens',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer) {\n const { password, readonly, cidr_whitelist } = req.body;\n const { name } = req.remote_user;\n\n if (!_.isBoolean(readonly) || !_.isArray(cidr_whitelist)) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_DATA, SUPPORT_ERRORS.PARAMETERS_NOT_VALID));\n }\n\n auth.authenticate(name, password, async (err, user: RemoteUser) => {\n if (err) {\n const errorCode = err.message ? HTTP_STATUS.UNAUTHORIZED : HTTP_STATUS.INTERNAL_ERROR;\n return next(errorUtils.getCode(errorCode, err.message));\n }\n\n req.remote_user = user;\n\n if (!_.isFunction(storage.saveToken)) {\n return next(\n errorUtils.getCode(HTTP_STATUS.NOT_IMPLEMENTED, SUPPORT_ERRORS.STORAGE_NOT_IMPLEMENT)\n );\n }\n\n try {\n const token = await getApiToken(auth, config, user, password);\n if (!token) {\n throw errorUtils.getInternalError();\n }\n\n const key = stringToMD5(token);\n // TODO: use a utility here\n const maskedToken = mask(token, 5);\n const created = new Date().getTime();\n\n /**\n * cidr_whitelist: is not being used, we pass it through\n * token: we do not store the real token (it is generated once and retrieved\n * to the user), just a mask of it.\n */\n const saveToken: Token = {\n user: name,\n token: maskedToken,\n key,\n cidr: cidr_whitelist,\n readonly,\n created,\n };\n\n await storage.saveToken(saveToken);\n logger.debug({ key, name }, 'token @{key} was created for user @{name}');\n return next(\n normalizeToken({\n token,\n user: name,\n key: saveToken.key,\n cidr: cidr_whitelist,\n readonly,\n created: saveToken.created,\n })\n );\n } catch (error: any) {\n logger.error({ error: error.msg }, 'token creation has failed: @{error}');\n return next(errorUtils.getInternalError(error.message));\n }\n });\n }\n );\n\n route.delete(\n '/-/npm/v1/tokens/token/:tokenKey',\n async (req: $RequestExtend, res: Response, next: $NextFunctionVer) => {\n const {\n params: { tokenKey },\n } = req;\n const { name } = req.remote_user;\n\n if (_.isNil(name) === false) {\n logger.debug({ name }, '@{name} has requested remove a token');\n try {\n await storage.deleteToken(name, tokenKey);\n logger.info({ tokenKey, name }, 'token id @{tokenKey} was revoked for user @{name}');\n return next({});\n } catch (error: any) {\n logger.error({ error: error.msg }, 'token creation has failed: @{error}');\n return next(errorUtils.getCode(HTTP_STATUS.INTERNAL_ERROR, error.message));\n }\n }\n return next(errorUtils.getUnauthorized());\n }\n );\n}\n"],"file":"token.js"}
package/build/whoami.js CHANGED
@@ -9,7 +9,6 @@ var _debug = _interopRequireDefault(require("debug"));
9
9
 
10
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
11
 
12
- // import { getUnauthorized } from '@verdaccio/commons-api';
13
12
  const debug = (0, _debug.default)('verdaccio:api:user');
14
13
 
15
14
  function _default(route) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/whoami.ts"],"names":["debug","route","get","req","res","next","headers","referer","username","remote_user","name"],"mappings":";;;;;;;AACA;;;;AAEA;AAEA,MAAMA,KAAK,GAAG,oBAAW,oBAAX,CAAd;;AAEe,kBAAUC,KAAV,EAA+B;AAC5CA,EAAAA,KAAK,CAACC,GAAN,CAAU,SAAV,EAAqB,CAACC,GAAD,EAAsBC,GAAtB,EAAqCC,IAArC,KAAsE;AACzFL,IAAAA,KAAK,CAAC,kBAAD,CAAL;;AACA,QAAIG,GAAG,CAACG,OAAJ,CAAYC,OAAZ,KAAwB,QAA5B,EAAsC;AACpC,YAAMC,QAAQ,GAAGL,GAAG,CAACM,WAAJ,CAAgBC,IAAjC,CADoC,CAEpC;AACA;AACA;AACA;AACA;;AACAV,MAAAA,KAAK,CAAC,wBAAD,CAAL;AACA,aAAOK,IAAI,CAAC;AAAEG,QAAAA,QAAQ,EAAEA;AAAZ,OAAD,CAAX;AACD,KATD,MASO;AACLR,MAAAA,KAAK,CAAC,6BAAD,CAAL,CADK,CAEL;;AACA,aAAOK,IAAI,CAAC,OAAD,CAAX;AACD;AACF,GAhBD;AAkBAJ,EAAAA,KAAK,CAACC,GAAN,CAAU,WAAV,EAAuB,CAACC,GAAD,EAAsBC,GAAtB,EAAqCC,IAArC,KAAqE;AAC1F,UAAMG,QAAQ,GAAGL,GAAG,CAACM,WAAJ,CAAgBC,IAAjC,CAD0F,CAE1F;AACA;AACA;AACA;AACA;;AAEAV,IAAAA,KAAK,CAAC,qBAAD,EAAwBQ,QAAxB,CAAL;AACA,WAAOH,IAAI,CAAC;AAAEG,MAAAA,QAAQ,EAAEA;AAAZ,KAAD,CAAX;AACD,GAVD;AAWD","sourcesContent":["import { Response, Router } from 'express';\nimport buildDebug from 'debug';\nimport { $RequestExtend, $NextFunctionVer } from '../types/custom';\n// import { getUnauthorized } from '@verdaccio/commons-api';\n\nconst debug = buildDebug('verdaccio:api:user');\n\nexport default function (route: Router): void {\n route.get('/whoami', (req: $RequestExtend, res: Response, next: $NextFunctionVer): void => {\n debug('whoami: reditect');\n if (req.headers.referer === 'whoami') {\n const username = req.remote_user.name;\n // FIXME: this service should return 401 if user missing\n // if (!username) {\n // debug('whoami: user not found');\n // return next(getUnauthorized('Unauthorized'));\n // }\n debug('whoami: logged by user');\n return next({ username: username });\n } else {\n debug('whoami: redirect next route');\n // redirect to the route below\n return next('route');\n }\n });\n\n route.get('/-/whoami', (req: $RequestExtend, res: Response, next: $NextFunctionVer): any => {\n const username = req.remote_user.name;\n // FIXME: this service should return 401 if user missing\n // if (!username) {\n // debug('whoami: user not found');\n // return next(getUnauthorized('Unauthorized'));\n // }\n\n debug('whoami: response %o', username);\n return next({ username: username });\n });\n}\n"],"file":"whoami.js"}
1
+ {"version":3,"sources":["../src/whoami.ts"],"names":["debug","route","get","req","res","next","headers","referer","username","remote_user","name"],"mappings":";;;;;;;AACA;;;;AAGA,MAAMA,KAAK,GAAG,oBAAW,oBAAX,CAAd;;AAEe,kBAAUC,KAAV,EAA+B;AAC5CA,EAAAA,KAAK,CAACC,GAAN,CAAU,SAAV,EAAqB,CAACC,GAAD,EAAsBC,GAAtB,EAAqCC,IAArC,KAAsE;AACzFL,IAAAA,KAAK,CAAC,kBAAD,CAAL;;AACA,QAAIG,GAAG,CAACG,OAAJ,CAAYC,OAAZ,KAAwB,QAA5B,EAAsC;AACpC,YAAMC,QAAQ,GAAGL,GAAG,CAACM,WAAJ,CAAgBC,IAAjC,CADoC,CAEpC;AACA;AACA;AACA;AACA;;AACAV,MAAAA,KAAK,CAAC,wBAAD,CAAL;AACA,aAAOK,IAAI,CAAC;AAAEG,QAAAA,QAAQ,EAAEA;AAAZ,OAAD,CAAX;AACD,KATD,MASO;AACLR,MAAAA,KAAK,CAAC,6BAAD,CAAL,CADK,CAEL;;AACA,aAAOK,IAAI,CAAC,OAAD,CAAX;AACD;AACF,GAhBD;AAkBAJ,EAAAA,KAAK,CAACC,GAAN,CAAU,WAAV,EAAuB,CAACC,GAAD,EAAsBC,GAAtB,EAAqCC,IAArC,KAAqE;AAC1F,UAAMG,QAAQ,GAAGL,GAAG,CAACM,WAAJ,CAAgBC,IAAjC,CAD0F,CAE1F;AACA;AACA;AACA;AACA;;AAEAV,IAAAA,KAAK,CAAC,qBAAD,EAAwBQ,QAAxB,CAAL;AACA,WAAOH,IAAI,CAAC;AAAEG,MAAAA,QAAQ,EAAEA;AAAZ,KAAD,CAAX;AACD,GAVD;AAWD","sourcesContent":["import { Response, Router } from 'express';\nimport buildDebug from 'debug';\nimport { $RequestExtend, $NextFunctionVer } from '../types/custom';\n\nconst debug = buildDebug('verdaccio:api:user');\n\nexport default function (route: Router): void {\n route.get('/whoami', (req: $RequestExtend, res: Response, next: $NextFunctionVer): void => {\n debug('whoami: reditect');\n if (req.headers.referer === 'whoami') {\n const username = req.remote_user.name;\n // FIXME: this service should return 401 if user missing\n // if (!username) {\n // debug('whoami: user not found');\n // return next(getUnauthorized('Unauthorized'));\n // }\n debug('whoami: logged by user');\n return next({ username: username });\n } else {\n debug('whoami: redirect next route');\n // redirect to the route below\n return next('route');\n }\n });\n\n route.get('/-/whoami', (req: $RequestExtend, res: Response, next: $NextFunctionVer): any => {\n const username = req.remote_user.name;\n // FIXME: this service should return 401 if user missing\n // if (!username) {\n // debug('whoami: user not found');\n // return next(getUnauthorized('Unauthorized'));\n // }\n\n debug('whoami: response %o', username);\n return next({ username: username });\n });\n}\n"],"file":"whoami.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdaccio/api",
3
- "version": "6.0.0-6-next.12",
3
+ "version": "6.0.0-6-next.16",
4
4
  "description": "loaders logic",
5
5
  "main": "./build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -25,20 +25,21 @@
25
25
  "verdaccio"
26
26
  ],
27
27
  "engines": {
28
- "node": ">=10",
28
+ "node": ">=14",
29
29
  "npm": ">=6"
30
30
  },
31
31
  "license": "MIT",
32
32
  "dependencies": {
33
- "@verdaccio/auth": "6.0.0-6-next.9",
34
- "@verdaccio/commons-api": "11.0.0-alpha.3",
35
- "@verdaccio/config": "6.0.0-6-next.7",
36
- "@verdaccio/hooks": "6.0.0-6-next.4",
37
- "@verdaccio/logger": "6.0.0-6-next.4",
38
- "@verdaccio/middleware": "6.0.0-6-next.9",
39
- "@verdaccio/store": "6.0.0-6-next.10",
40
- "@verdaccio/tarball": "11.0.0-6-next.6",
41
- "@verdaccio/utils": "6.0.0-6-next.5",
33
+ "@verdaccio/auth": "6.0.0-6-next.13",
34
+ "@verdaccio/config": "6.0.0-6-next.9",
35
+ "@verdaccio/core": "6.0.0-6-next.2",
36
+ "@verdaccio/hooks": "6.0.0-6-next.8",
37
+ "@verdaccio/logger": "6.0.0-6-next.6",
38
+ "@verdaccio/middleware": "6.0.0-6-next.13",
39
+ "@verdaccio/store": "6.0.0-6-next.14",
40
+ "@verdaccio/tarball": "11.0.0-6-next.8",
41
+ "@verdaccio/utils": "6.0.0-6-next.7",
42
+ "abortcontroller-polyfill": "1.7.3",
42
43
  "cookies": "0.8.0",
43
44
  "debug": "4.3.2",
44
45
  "express": "4.17.1",
@@ -47,8 +48,10 @@
47
48
  "semver": "7.3.5"
48
49
  },
49
50
  "devDependencies": {
50
- "@verdaccio/server": "6.0.0-6-next.17",
51
- "@verdaccio/types": "11.0.0-6-next.7",
51
+ "@types/node": "16.9.1",
52
+ "@verdaccio/server": "6.0.0-6-next.21",
53
+ "@verdaccio/types": "11.0.0-6-next.9",
54
+ "@verdaccio/helper": "1.0.0",
52
55
  "body-parser": "1.19.0",
53
56
  "lodash": "4.17.21",
54
57
  "supertest": "6.1.6"
package/src/dist-tags.ts CHANGED
@@ -3,13 +3,13 @@ import _ from 'lodash';
3
3
  import { Router } from 'express';
4
4
 
5
5
  import { media, allow } from '@verdaccio/middleware';
6
- import { API_MESSAGE, HTTP_STATUS, DIST_TAGS, VerdaccioError } from '@verdaccio/commons-api';
6
+ import { constants, VerdaccioError } from '@verdaccio/core';
7
7
  import { Package } from '@verdaccio/types';
8
- import { IStorageHandler } from '@verdaccio/store';
8
+ import { Storage } from '@verdaccio/store';
9
9
  import { IAuth } from '@verdaccio/auth';
10
10
  import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types/custom';
11
11
 
12
- export default function (route: Router, auth: IAuth, storage: IStorageHandler): void {
12
+ export default function (route: Router, auth: IAuth, storage: Storage): void {
13
13
  const can = allow(auth);
14
14
  const tag_package_version = function (
15
15
  req: $RequestExtend,
@@ -26,8 +26,8 @@ export default function (route: Router, auth: IAuth, storage: IStorageHandler):
26
26
  if (err) {
27
27
  return next(err);
28
28
  }
29
- res.status(HTTP_STATUS.CREATED);
30
- return next({ ok: API_MESSAGE.TAG_ADDED });
29
+ res.status(constants.HTTP_STATUS.CREATED);
30
+ return next({ ok: constants.API_MESSAGE.TAG_ADDED });
31
31
  });
32
32
  };
33
33
 
@@ -58,9 +58,9 @@ export default function (route: Router, auth: IAuth, storage: IStorageHandler):
58
58
  if (err) {
59
59
  return next(err);
60
60
  }
61
- res.status(HTTP_STATUS.CREATED);
61
+ res.status(constants.HTTP_STATUS.CREATED);
62
62
  return next({
63
- ok: API_MESSAGE.TAG_REMOVED,
63
+ ok: constants.API_MESSAGE.TAG_REMOVED,
64
64
  });
65
65
  });
66
66
  }
@@ -79,7 +79,7 @@ export default function (route: Router, auth: IAuth, storage: IStorageHandler):
79
79
  return next(err);
80
80
  }
81
81
 
82
- next(info[DIST_TAGS]);
82
+ next(info[constants.DIST_TAGS]);
83
83
  },
84
84
  });
85
85
  }
@@ -96,9 +96,9 @@ export default function (route: Router, auth: IAuth, storage: IStorageHandler):
96
96
  if (err) {
97
97
  return next(err);
98
98
  }
99
- res.status(HTTP_STATUS.CREATED);
99
+ res.status(constants.HTTP_STATUS.CREATED);
100
100
  return next({
101
- ok: API_MESSAGE.TAG_UPDATED,
101
+ ok: constants.API_MESSAGE.TAG_UPDATED,
102
102
  });
103
103
  }
104
104
  );
package/src/index.ts CHANGED
@@ -7,9 +7,10 @@ import {
7
7
  antiLoop,
8
8
  } from '@verdaccio/middleware';
9
9
  import { IAuth } from '@verdaccio/auth';
10
- import { IStorageHandler } from '@verdaccio/store';
10
+ import { Storage } from '@verdaccio/store';
11
11
  import { Config } from '@verdaccio/types';
12
12
  import bodyParser from 'body-parser';
13
+ import semver from 'semver';
13
14
 
14
15
  import whoami from './whoami';
15
16
  import ping from './ping';
@@ -23,7 +24,11 @@ import profile from './v1/profile';
23
24
  import token from './v1/token';
24
25
  import v1Search from './v1/search';
25
26
 
26
- export default function (config: Config, auth: IAuth, storage: IStorageHandler): Router {
27
+ if (semver.lte(process.version, 'v15.0.0')) {
28
+ global.AbortController = require('abortcontroller-polyfill/dist/cjs-ponyfill').AbortController;
29
+ }
30
+
31
+ export default function (config: Config, auth: IAuth, storage: Storage): Router {
27
32
  /* eslint new-cap:off */
28
33
  const app = express.Router();
29
34
  /* eslint new-cap:off */
@@ -52,19 +57,15 @@ export default function (config: Config, auth: IAuth, storage: IStorageHandler):
52
57
  whoami(app);
53
58
  pkg(app, auth, storage, config);
54
59
  profile(app, auth);
55
- search(app, auth, storage);
60
+ // @deprecated endpoint, 404 by default
61
+ search(app);
56
62
  user(app, auth, config);
57
63
  distTags(app, auth, storage);
58
64
  publish(app, auth, storage, config);
59
65
  ping(app);
60
66
  stars(app, storage);
61
-
62
- if (config?.flags?.search === true) {
63
- v1Search(app, auth, storage);
64
- }
65
-
66
- if (config?.flags?.token === true) {
67
- token(app, auth, storage, config);
68
- }
67
+ // @ts-ignore
68
+ v1Search(app, auth, storage);
69
+ token(app, auth, storage, config);
69
70
  return app;
70
71
  }