@verdaccio/api 6.0.0-6-next.34 → 6.0.0-6-next.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/build/dist-tags.js +2 -13
- package/build/dist-tags.js.map +1 -1
- package/build/index.js +14 -30
- package/build/index.js.map +1 -1
- package/build/package.js +3 -15
- package/build/package.js.map +1 -1
- package/build/ping.js +0 -1
- package/build/ping.js.map +1 -1
- package/build/publish.js +4 -19
- package/build/publish.js.map +1 -1
- package/build/search.js +0 -4
- package/build/search.js.map +1 -1
- package/build/stars.js +0 -6
- package/build/stars.js.map +1 -1
- package/build/user.js +5 -27
- package/build/user.js.map +1 -1
- package/build/v1/profile.js +0 -11
- package/build/v1/profile.js.map +1 -1
- package/build/v1/search.js +1 -13
- package/build/v1/search.js.map +1 -1
- package/build/v1/token.d.ts +1 -1
- package/build/v1/token.js +7 -35
- package/build/v1/token.js.map +1 -1
- package/build/whoami.js +0 -8
- package/build/whoami.js.map +1 -1
- package/package.json +11 -11
package/build/user.js
CHANGED
|
@@ -4,23 +4,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = _default;
|
|
7
|
-
|
|
8
7
|
var _debug = _interopRequireDefault(require("debug"));
|
|
9
|
-
|
|
10
8
|
var _auth = require("@verdaccio/auth");
|
|
11
|
-
|
|
12
9
|
var _config = require("@verdaccio/config");
|
|
13
|
-
|
|
14
10
|
var _core = require("@verdaccio/core");
|
|
15
|
-
|
|
16
11
|
var _logger = require("@verdaccio/logger");
|
|
17
|
-
|
|
18
12
|
var _utils = require("@verdaccio/utils");
|
|
19
|
-
|
|
20
13
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
21
|
-
|
|
22
14
|
const debug = (0, _debug.default)('verdaccio:api:user');
|
|
23
|
-
|
|
24
15
|
function _default(route, auth, config) {
|
|
25
16
|
route.get('/-/user/:org_couchdb_user', function (req, res, next) {
|
|
26
17
|
debug('verifying user');
|
|
@@ -31,6 +22,7 @@ function _default(route, auth, config) {
|
|
|
31
22
|
ok: message
|
|
32
23
|
});
|
|
33
24
|
});
|
|
25
|
+
|
|
34
26
|
/**
|
|
35
27
|
*
|
|
36
28
|
* body example
|
|
@@ -48,17 +40,14 @@ function _default(route, auth, config) {
|
|
|
48
40
|
* @param {Auth} auth
|
|
49
41
|
* @param {Config} config
|
|
50
42
|
*/
|
|
51
|
-
|
|
52
43
|
route.put('/-/user/:org_couchdb_user/:_rev?/:revision?', function (req, res, next) {
|
|
53
44
|
var _req$remote_user;
|
|
54
|
-
|
|
55
45
|
const {
|
|
56
46
|
name,
|
|
57
47
|
password
|
|
58
48
|
} = req.body;
|
|
59
49
|
debug('login or adduser');
|
|
60
50
|
const remoteName = req === null || req === void 0 ? void 0 : (_req$remote_user = req.remote_user) === null || _req$remote_user === void 0 ? void 0 : _req$remote_user.name;
|
|
61
|
-
|
|
62
51
|
if (typeof remoteName !== 'undefined' && typeof name === 'string' && remoteName === name) {
|
|
63
52
|
debug('login: no remote user detected');
|
|
64
53
|
auth.authenticate(name, password, async function callbackAuthenticate(err, user) {
|
|
@@ -67,18 +56,14 @@ function _default(route, auth, config) {
|
|
|
67
56
|
name,
|
|
68
57
|
err
|
|
69
58
|
}, 'authenticating for user @{username} failed. Error: @{err.message}');
|
|
70
|
-
|
|
71
59
|
return next(_core.errorUtils.getCode(_core.HTTP_STATUS.UNAUTHORIZED, _core.API_ERROR.BAD_USERNAME_PASSWORD));
|
|
72
60
|
}
|
|
73
|
-
|
|
74
61
|
const restoredRemoteUser = (0, _config.createRemoteUser)(name, (user === null || user === void 0 ? void 0 : user.groups) || []);
|
|
75
62
|
const token = await (0, _auth.getApiToken)(auth, config, restoredRemoteUser, password);
|
|
76
63
|
debug('login: new token');
|
|
77
|
-
|
|
78
64
|
if (!token) {
|
|
79
65
|
return next(_core.errorUtils.getUnauthorized());
|
|
80
66
|
}
|
|
81
|
-
|
|
82
67
|
res.status(_core.HTTP_STATUS.CREATED);
|
|
83
68
|
res.set(_core.HEADERS.CACHE_CONTROL, 'no-cache, no-store');
|
|
84
69
|
const message = (0, _utils.getAuthenticatedMessage)(req.remote_user.name);
|
|
@@ -90,36 +75,29 @@ function _default(route, auth, config) {
|
|
|
90
75
|
});
|
|
91
76
|
} else {
|
|
92
77
|
var _config$serverSetting;
|
|
93
|
-
|
|
94
78
|
if (_core.validatioUtils.validatePassword(password, config === null || config === void 0 ? void 0 : (_config$serverSetting = config.serverSettings) === null || _config$serverSetting === void 0 ? void 0 : _config$serverSetting.passwordValidationRegex) === false) {
|
|
95
|
-
debug('adduser: invalid password');
|
|
96
|
-
|
|
79
|
+
debug('adduser: invalid password');
|
|
80
|
+
// eslint-disable-next-line new-cap
|
|
97
81
|
return next(_core.errorUtils.getCode(_core.HTTP_STATUS.BAD_REQUEST, _core.API_ERROR.PASSWORD_SHORT));
|
|
98
82
|
}
|
|
99
|
-
|
|
100
83
|
auth.add_user(name, password, async function (err, user) {
|
|
101
84
|
if (err) {
|
|
102
85
|
if (err.status >= _core.HTTP_STATUS.BAD_REQUEST && err.status < _core.HTTP_STATUS.INTERNAL_ERROR) {
|
|
103
|
-
debug('adduser: error on create user');
|
|
86
|
+
debug('adduser: error on create user');
|
|
87
|
+
// With npm registering is the same as logging in,
|
|
104
88
|
// and npm accepts only an 409 error.
|
|
105
89
|
// So, changing status code here.
|
|
106
|
-
|
|
107
90
|
return next(_core.errorUtils.getCode(err.status, err.message) || _core.errorUtils.getConflict(err.message));
|
|
108
91
|
}
|
|
109
|
-
|
|
110
92
|
return next(err);
|
|
111
93
|
}
|
|
112
|
-
|
|
113
94
|
const token = name && password ? await (0, _auth.getApiToken)(auth, config, user, password) : undefined;
|
|
114
|
-
|
|
115
95
|
if (token) {
|
|
116
96
|
debug('adduser: new token %o', (0, _utils.mask)(token, 4));
|
|
117
97
|
}
|
|
118
|
-
|
|
119
98
|
if (!token) {
|
|
120
99
|
return next(_core.errorUtils.getUnauthorized());
|
|
121
100
|
}
|
|
122
|
-
|
|
123
101
|
req.remote_user = user;
|
|
124
102
|
res.status(_core.HTTP_STATUS.CREATED);
|
|
125
103
|
res.set(_core.HEADERS.CACHE_CONTROL, 'no-cache, no-store');
|
package/build/user.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.js","names":["debug","buildDebug","route","auth","config","get","req","res","next","message","getAuthenticatedMessage","remote_user","name","status","HTTP_STATUS","OK","ok","put","password","body","remoteName","authenticate","callbackAuthenticate","err","user","logger","trace","errorUtils","getCode","UNAUTHORIZED","API_ERROR","BAD_USERNAME_PASSWORD","restoredRemoteUser","createRemoteUser","groups","token","getApiToken","getUnauthorized","CREATED","set","HEADERS","CACHE_CONTROL","validatioUtils","validatePassword","serverSettings","passwordValidationRegex","BAD_REQUEST","PASSWORD_SHORT","add_user","INTERNAL_ERROR","getConflict","undefined","mask","delete","API_MESSAGE","LOGGED_OUT"],"sources":["../src/user.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Response, Router } from 'express';\n\nimport { getApiToken } from '@verdaccio/auth';\nimport { Auth } from '@verdaccio/auth';\nimport { createRemoteUser } from '@verdaccio/config';\nimport {\n API_ERROR,\n API_MESSAGE,\n HEADERS,\n HTTP_STATUS,\n errorUtils,\n validatioUtils,\n} from '@verdaccio/core';\nimport { logger } from '@verdaccio/logger';\nimport { Config, RemoteUser } from '@verdaccio/types';\nimport { getAuthenticatedMessage, mask } from '@verdaccio/utils';\n\nimport { $NextFunctionVer, $RequestExtend } from '../types/custom';\n\nconst debug = buildDebug('verdaccio:api:user');\n\nexport default function (route: Router, auth: Auth, config: Config): void {\n route.get(\n '/-/user/:org_couchdb_user',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n debug('verifying user');\n const message = getAuthenticatedMessage(req.remote_user.name);\n debug('user authenticated message %o', message);\n res.status(HTTP_STATUS.OK);\n next({\n ok: message,\n });\n }\n );\n\n /**\n * \n * body example\n * req.body = {\n _id: \"org.couchdb.user:jjjj\",\n name: \"jjjj\",\n password: \"jjjj\",\n type: \"user\",\n roles: [],\n date: \"2022-07-08T15:51:04.002Z\",\n }\n * \n * @export\n * @param {Router} route\n * @param {Auth} auth\n * @param {Config} config\n */\n route.put(\n '/-/user/:org_couchdb_user/:_rev?/:revision?',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n const { name, password } = req.body;\n debug('login or adduser');\n const remoteName = req?.remote_user?.name;\n\n if (typeof remoteName !== 'undefined' && typeof name === 'string' && remoteName === name) {\n debug('login: no remote user detected');\n auth.authenticate(\n name,\n password,\n async function callbackAuthenticate(err, user): Promise<void> {\n if (err) {\n logger.trace(\n { name, err },\n 'authenticating for user @{username} failed. Error: @{err.message}'\n );\n return next(\n errorUtils.getCode(HTTP_STATUS.UNAUTHORIZED, API_ERROR.BAD_USERNAME_PASSWORD)\n );\n }\n\n const restoredRemoteUser: RemoteUser = createRemoteUser(name, user?.groups || []);\n const token = await getApiToken(auth, config, restoredRemoteUser, password);\n debug('login: new token');\n if (!token) {\n return next(errorUtils.getUnauthorized());\n }\n\n res.status(HTTP_STATUS.CREATED);\n res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');\n\n const message = getAuthenticatedMessage(req.remote_user.name);\n debug('login: created user message %o', message);\n\n return next({\n ok: message,\n token,\n });\n }\n );\n } else {\n if (\n validatioUtils.validatePassword(\n password,\n config?.serverSettings?.passwordValidationRegex\n ) === false\n ) {\n debug('adduser: invalid password');\n // eslint-disable-next-line new-cap\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.PASSWORD_SHORT));\n }\n\n auth.add_user(name, password, async function (err, user): Promise<void> {\n if (err) {\n if (err.status >= HTTP_STATUS.BAD_REQUEST && err.status < HTTP_STATUS.INTERNAL_ERROR) {\n debug('adduser: error on create user');\n // With npm registering is the same as logging in,\n // and npm accepts only an 409 error.\n // So, changing status code here.\n return next(\n errorUtils.getCode(err.status, err.message) || errorUtils.getConflict(err.message)\n );\n }\n return next(err);\n }\n\n const token =\n name && password\n ? await getApiToken(auth, config, user as RemoteUser, password)\n : undefined;\n if (token) {\n debug('adduser: new token %o', mask(token as string, 4));\n }\n if (!token) {\n return next(errorUtils.getUnauthorized());\n }\n\n req.remote_user = user;\n res.status(HTTP_STATUS.CREATED);\n res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');\n debug('adduser: user has been created');\n return next({\n ok: `user '${req.body.name}' created`,\n token,\n });\n });\n }\n }\n );\n\n route.delete(\n '/-/user/token/*',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n res.status(HTTP_STATUS.OK);\n next({\n ok: API_MESSAGE.LOGGED_OUT,\n });\n }\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"user.js","names":["debug","buildDebug","route","auth","config","get","req","res","next","message","getAuthenticatedMessage","remote_user","name","status","HTTP_STATUS","OK","ok","put","password","body","remoteName","authenticate","callbackAuthenticate","err","user","logger","trace","errorUtils","getCode","UNAUTHORIZED","API_ERROR","BAD_USERNAME_PASSWORD","restoredRemoteUser","createRemoteUser","groups","token","getApiToken","getUnauthorized","CREATED","set","HEADERS","CACHE_CONTROL","validatioUtils","validatePassword","serverSettings","passwordValidationRegex","BAD_REQUEST","PASSWORD_SHORT","add_user","INTERNAL_ERROR","getConflict","undefined","mask","delete","API_MESSAGE","LOGGED_OUT"],"sources":["../src/user.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { Response, Router } from 'express';\n\nimport { getApiToken } from '@verdaccio/auth';\nimport { Auth } from '@verdaccio/auth';\nimport { createRemoteUser } from '@verdaccio/config';\nimport {\n API_ERROR,\n API_MESSAGE,\n HEADERS,\n HTTP_STATUS,\n errorUtils,\n validatioUtils,\n} from '@verdaccio/core';\nimport { logger } from '@verdaccio/logger';\nimport { Config, RemoteUser } from '@verdaccio/types';\nimport { getAuthenticatedMessage, mask } from '@verdaccio/utils';\n\nimport { $NextFunctionVer, $RequestExtend } from '../types/custom';\n\nconst debug = buildDebug('verdaccio:api:user');\n\nexport default function (route: Router, auth: Auth, config: Config): void {\n route.get(\n '/-/user/:org_couchdb_user',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n debug('verifying user');\n const message = getAuthenticatedMessage(req.remote_user.name);\n debug('user authenticated message %o', message);\n res.status(HTTP_STATUS.OK);\n next({\n ok: message,\n });\n }\n );\n\n /**\n * \n * body example\n * req.body = {\n _id: \"org.couchdb.user:jjjj\",\n name: \"jjjj\",\n password: \"jjjj\",\n type: \"user\",\n roles: [],\n date: \"2022-07-08T15:51:04.002Z\",\n }\n * \n * @export\n * @param {Router} route\n * @param {Auth} auth\n * @param {Config} config\n */\n route.put(\n '/-/user/:org_couchdb_user/:_rev?/:revision?',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n const { name, password } = req.body;\n debug('login or adduser');\n const remoteName = req?.remote_user?.name;\n\n if (typeof remoteName !== 'undefined' && typeof name === 'string' && remoteName === name) {\n debug('login: no remote user detected');\n auth.authenticate(\n name,\n password,\n async function callbackAuthenticate(err, user): Promise<void> {\n if (err) {\n logger.trace(\n { name, err },\n 'authenticating for user @{username} failed. Error: @{err.message}'\n );\n return next(\n errorUtils.getCode(HTTP_STATUS.UNAUTHORIZED, API_ERROR.BAD_USERNAME_PASSWORD)\n );\n }\n\n const restoredRemoteUser: RemoteUser = createRemoteUser(name, user?.groups || []);\n const token = await getApiToken(auth, config, restoredRemoteUser, password);\n debug('login: new token');\n if (!token) {\n return next(errorUtils.getUnauthorized());\n }\n\n res.status(HTTP_STATUS.CREATED);\n res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');\n\n const message = getAuthenticatedMessage(req.remote_user.name);\n debug('login: created user message %o', message);\n\n return next({\n ok: message,\n token,\n });\n }\n );\n } else {\n if (\n validatioUtils.validatePassword(\n password,\n config?.serverSettings?.passwordValidationRegex\n ) === false\n ) {\n debug('adduser: invalid password');\n // eslint-disable-next-line new-cap\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.PASSWORD_SHORT));\n }\n\n auth.add_user(name, password, async function (err, user): Promise<void> {\n if (err) {\n if (err.status >= HTTP_STATUS.BAD_REQUEST && err.status < HTTP_STATUS.INTERNAL_ERROR) {\n debug('adduser: error on create user');\n // With npm registering is the same as logging in,\n // and npm accepts only an 409 error.\n // So, changing status code here.\n return next(\n errorUtils.getCode(err.status, err.message) || errorUtils.getConflict(err.message)\n );\n }\n return next(err);\n }\n\n const token =\n name && password\n ? await getApiToken(auth, config, user as RemoteUser, password)\n : undefined;\n if (token) {\n debug('adduser: new token %o', mask(token as string, 4));\n }\n if (!token) {\n return next(errorUtils.getUnauthorized());\n }\n\n req.remote_user = user;\n res.status(HTTP_STATUS.CREATED);\n res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');\n debug('adduser: user has been created');\n return next({\n ok: `user '${req.body.name}' created`,\n token,\n });\n });\n }\n }\n );\n\n route.delete(\n '/-/user/token/*',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n res.status(HTTP_STATUS.OK);\n next({\n ok: API_MESSAGE.LOGGED_OUT,\n });\n }\n );\n}\n"],"mappings":";;;;;;AAAA;AAGA;AAEA;AACA;AAQA;AAEA;AAAiE;AAIjE,MAAMA,KAAK,GAAG,IAAAC,cAAU,EAAC,oBAAoB,CAAC;AAE/B,kBAAUC,KAAa,EAAEC,IAAU,EAAEC,MAAc,EAAQ;EACxEF,KAAK,CAACG,GAAG,CACP,2BAA2B,EAC3B,UAAUC,GAAmB,EAAEC,GAAa,EAAEC,IAAsB,EAAQ;IAC1ER,KAAK,CAAC,gBAAgB,CAAC;IACvB,MAAMS,OAAO,GAAG,IAAAC,8BAAuB,EAACJ,GAAG,CAACK,WAAW,CAACC,IAAI,CAAC;IAC7DZ,KAAK,CAAC,+BAA+B,EAAES,OAAO,CAAC;IAC/CF,GAAG,CAACM,MAAM,CAACC,iBAAW,CAACC,EAAE,CAAC;IAC1BP,IAAI,CAAC;MACHQ,EAAE,EAAEP;IACN,CAAC,CAAC;EACJ,CAAC,CACF;;EAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEP,KAAK,CAACe,GAAG,CACP,6CAA6C,EAC7C,UAAUX,GAAmB,EAAEC,GAAa,EAAEC,IAAsB,EAAQ;IAAA;IAC1E,MAAM;MAAEI,IAAI;MAAEM;IAAS,CAAC,GAAGZ,GAAG,CAACa,IAAI;IACnCnB,KAAK,CAAC,kBAAkB,CAAC;IACzB,MAAMoB,UAAU,GAAGd,GAAG,aAAHA,GAAG,2CAAHA,GAAG,CAAEK,WAAW,qDAAhB,iBAAkBC,IAAI;IAEzC,IAAI,OAAOQ,UAAU,KAAK,WAAW,IAAI,OAAOR,IAAI,KAAK,QAAQ,IAAIQ,UAAU,KAAKR,IAAI,EAAE;MACxFZ,KAAK,CAAC,gCAAgC,CAAC;MACvCG,IAAI,CAACkB,YAAY,CACfT,IAAI,EACJM,QAAQ,EACR,eAAeI,oBAAoB,CAACC,GAAG,EAAEC,IAAI,EAAiB;QAC5D,IAAID,GAAG,EAAE;UACPE,cAAM,CAACC,KAAK,CACV;YAAEd,IAAI;YAAEW;UAAI,CAAC,EACb,mEAAmE,CACpE;UACD,OAAOf,IAAI,CACTmB,gBAAU,CAACC,OAAO,CAACd,iBAAW,CAACe,YAAY,EAAEC,eAAS,CAACC,qBAAqB,CAAC,CAC9E;QACH;QAEA,MAAMC,kBAA8B,GAAG,IAAAC,wBAAgB,EAACrB,IAAI,EAAE,CAAAY,IAAI,aAAJA,IAAI,uBAAJA,IAAI,CAAEU,MAAM,KAAI,EAAE,CAAC;QACjF,MAAMC,KAAK,GAAG,MAAM,IAAAC,iBAAW,EAACjC,IAAI,EAAEC,MAAM,EAAE4B,kBAAkB,EAAEd,QAAQ,CAAC;QAC3ElB,KAAK,CAAC,kBAAkB,CAAC;QACzB,IAAI,CAACmC,KAAK,EAAE;UACV,OAAO3B,IAAI,CAACmB,gBAAU,CAACU,eAAe,EAAE,CAAC;QAC3C;QAEA9B,GAAG,CAACM,MAAM,CAACC,iBAAW,CAACwB,OAAO,CAAC;QAC/B/B,GAAG,CAACgC,GAAG,CAACC,aAAO,CAACC,aAAa,EAAE,oBAAoB,CAAC;QAEpD,MAAMhC,OAAO,GAAG,IAAAC,8BAAuB,EAACJ,GAAG,CAACK,WAAW,CAACC,IAAI,CAAC;QAC7DZ,KAAK,CAAC,gCAAgC,EAAES,OAAO,CAAC;QAEhD,OAAOD,IAAI,CAAC;UACVQ,EAAE,EAAEP,OAAO;UACX0B;QACF,CAAC,CAAC;MACJ,CAAC,CACF;IACH,CAAC,MAAM;MAAA;MACL,IACEO,oBAAc,CAACC,gBAAgB,CAC7BzB,QAAQ,EACRd,MAAM,aAANA,MAAM,gDAANA,MAAM,CAAEwC,cAAc,0DAAtB,sBAAwBC,uBAAuB,CAChD,KAAK,KAAK,EACX;QACA7C,KAAK,CAAC,2BAA2B,CAAC;QAClC;QACA,OAAOQ,IAAI,CAACmB,gBAAU,CAACC,OAAO,CAACd,iBAAW,CAACgC,WAAW,EAAEhB,eAAS,CAACiB,cAAc,CAAC,CAAC;MACpF;MAEA5C,IAAI,CAAC6C,QAAQ,CAACpC,IAAI,EAAEM,QAAQ,EAAE,gBAAgBK,GAAG,EAAEC,IAAI,EAAiB;QACtE,IAAID,GAAG,EAAE;UACP,IAAIA,GAAG,CAACV,MAAM,IAAIC,iBAAW,CAACgC,WAAW,IAAIvB,GAAG,CAACV,MAAM,GAAGC,iBAAW,CAACmC,cAAc,EAAE;YACpFjD,KAAK,CAAC,+BAA+B,CAAC;YACtC;YACA;YACA;YACA,OAAOQ,IAAI,CACTmB,gBAAU,CAACC,OAAO,CAACL,GAAG,CAACV,MAAM,EAAEU,GAAG,CAACd,OAAO,CAAC,IAAIkB,gBAAU,CAACuB,WAAW,CAAC3B,GAAG,CAACd,OAAO,CAAC,CACnF;UACH;UACA,OAAOD,IAAI,CAACe,GAAG,CAAC;QAClB;QAEA,MAAMY,KAAK,GACTvB,IAAI,IAAIM,QAAQ,GACZ,MAAM,IAAAkB,iBAAW,EAACjC,IAAI,EAAEC,MAAM,EAAEoB,IAAI,EAAgBN,QAAQ,CAAC,GAC7DiC,SAAS;QACf,IAAIhB,KAAK,EAAE;UACTnC,KAAK,CAAC,uBAAuB,EAAE,IAAAoD,WAAI,EAACjB,KAAK,EAAY,CAAC,CAAC,CAAC;QAC1D;QACA,IAAI,CAACA,KAAK,EAAE;UACV,OAAO3B,IAAI,CAACmB,gBAAU,CAACU,eAAe,EAAE,CAAC;QAC3C;QAEA/B,GAAG,CAACK,WAAW,GAAGa,IAAI;QACtBjB,GAAG,CAACM,MAAM,CAACC,iBAAW,CAACwB,OAAO,CAAC;QAC/B/B,GAAG,CAACgC,GAAG,CAACC,aAAO,CAACC,aAAa,EAAE,oBAAoB,CAAC;QACpDzC,KAAK,CAAC,gCAAgC,CAAC;QACvC,OAAOQ,IAAI,CAAC;UACVQ,EAAE,EAAG,SAAQV,GAAG,CAACa,IAAI,CAACP,IAAK,WAAU;UACrCuB;QACF,CAAC,CAAC;MACJ,CAAC,CAAC;IACJ;EACF,CAAC,CACF;EAEDjC,KAAK,CAACmD,MAAM,CACV,iBAAiB,EACjB,UAAU/C,GAAmB,EAAEC,GAAa,EAAEC,IAAsB,EAAQ;IAC1ED,GAAG,CAACM,MAAM,CAACC,iBAAW,CAACC,EAAE,CAAC;IAC1BP,IAAI,CAAC;MACHQ,EAAE,EAAEsC,iBAAW,CAACC;IAClB,CAAC,CAAC;EACJ,CAAC,CACF;AACH"}
|
package/build/v1/profile.js
CHANGED
|
@@ -4,13 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = _default;
|
|
7
|
-
|
|
8
7
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
9
|
-
|
|
10
8
|
var _core = require("@verdaccio/core");
|
|
11
|
-
|
|
12
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
10
|
function _default(route, auth, config) {
|
|
15
11
|
function buildProfile(name) {
|
|
16
12
|
return {
|
|
@@ -24,12 +20,10 @@ function _default(route, auth, config) {
|
|
|
24
20
|
fullname: ''
|
|
25
21
|
};
|
|
26
22
|
}
|
|
27
|
-
|
|
28
23
|
route.get('/-/npm/v1/user', function (req, res, next) {
|
|
29
24
|
if (_lodash.default.isNil(req.remote_user.name) === false) {
|
|
30
25
|
return next(buildProfile(req.remote_user.name));
|
|
31
26
|
}
|
|
32
|
-
|
|
33
27
|
res.status(_core.HTTP_STATUS.UNAUTHORIZED);
|
|
34
28
|
return next({
|
|
35
29
|
message: _core.API_ERROR.MUST_BE_LOGGED
|
|
@@ -42,7 +36,6 @@ function _default(route, auth, config) {
|
|
|
42
36
|
message: _core.API_ERROR.MUST_BE_LOGGED
|
|
43
37
|
});
|
|
44
38
|
}
|
|
45
|
-
|
|
46
39
|
const {
|
|
47
40
|
password,
|
|
48
41
|
tfa
|
|
@@ -50,10 +43,8 @@ function _default(route, auth, config) {
|
|
|
50
43
|
const {
|
|
51
44
|
name
|
|
52
45
|
} = req.remote_user;
|
|
53
|
-
|
|
54
46
|
if (_lodash.default.isNil(password) === false) {
|
|
55
47
|
var _config$serverSetting;
|
|
56
|
-
|
|
57
48
|
if (_core.validatioUtils.validatePassword(password.new, config === null || config === void 0 ? void 0 : (_config$serverSetting = config.serverSettings) === null || _config$serverSetting === void 0 ? void 0 : _config$serverSetting.passwordValidationRegex) === false) {
|
|
58
49
|
/* eslint new-cap:off */
|
|
59
50
|
return next(_core.errorUtils.getCode(_core.HTTP_STATUS.UNAUTHORIZED, _core.API_ERROR.PASSWORD_SHORT));
|
|
@@ -64,11 +55,9 @@ function _default(route, auth, config) {
|
|
|
64
55
|
if (_lodash.default.isNull(err) === false) {
|
|
65
56
|
return next(_core.errorUtils.getCode(err.status, err.message) || _core.errorUtils.getConflict(err.message));
|
|
66
57
|
}
|
|
67
|
-
|
|
68
58
|
if (isUpdated) {
|
|
69
59
|
return next(buildProfile(req.remote_user.name));
|
|
70
60
|
}
|
|
71
|
-
|
|
72
61
|
return next(_core.errorUtils.getInternalError(_core.API_ERROR.INTERNAL_SERVER_ERROR));
|
|
73
62
|
});
|
|
74
63
|
} else if (_lodash.default.isNil(tfa) === false) {
|
package/build/v1/profile.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profile.js","names":["route","auth","config","buildProfile","name","tfa","email","email_verified","created","updated","cidr_whitelist","fullname","get","req","res","next","_","isNil","remote_user","status","HTTP_STATUS","UNAUTHORIZED","message","API_ERROR","MUST_BE_LOGGED","post","password","body","validatioUtils","validatePassword","new","serverSettings","passwordValidationRegex","errorUtils","getCode","PASSWORD_SHORT","changePassword","old","err","isUpdated","isNull","getConflict","getInternalError","INTERNAL_SERVER_ERROR","SERVICE_UNAVAILABLE","SUPPORT_ERRORS","TFA_DISABLED","INTERNAL_ERROR","APP_ERROR","PROFILE_ERROR"],"sources":["../../src/v1/profile.ts"],"sourcesContent":["import { Response, Router } from 'express';\nimport _ from 'lodash';\n\nimport { Auth } from '@verdaccio/auth';\nimport {\n API_ERROR,\n APP_ERROR,\n HTTP_STATUS,\n SUPPORT_ERRORS,\n errorUtils,\n validatioUtils,\n} from '@verdaccio/core';\nimport { Config } from '@verdaccio/types';\n\nimport { $NextFunctionVer, $RequestExtend } from '../../types/custom';\n\nexport interface Profile {\n tfa: boolean;\n name: string;\n email: string;\n email_verified: boolean;\n created: string;\n updated: string;\n cidr_whitelist: string[] | null;\n fullname: string;\n}\n\nexport default function (route: Router, auth: Auth, config: Config): void {\n function buildProfile(name: string): Profile {\n return {\n tfa: false,\n name,\n email: '',\n email_verified: false,\n created: '',\n updated: '',\n cidr_whitelist: null,\n fullname: '',\n };\n }\n\n route.get(\n '/-/npm/v1/user',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n if (_.isNil(req.remote_user.name) === false) {\n return next(buildProfile(req.remote_user.name));\n }\n\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n );\n\n route.post(\n '/-/npm/v1/user',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n if (_.isNil(req.remote_user.name)) {\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n\n const { password, tfa } = req.body;\n const { name } = req.remote_user;\n\n if (_.isNil(password) === false) {\n if (\n validatioUtils.validatePassword(\n password.new,\n config?.serverSettings?.passwordValidationRegex\n ) === false\n ) {\n /* eslint new-cap:off */\n return next(errorUtils.getCode(HTTP_STATUS.UNAUTHORIZED, API_ERROR.PASSWORD_SHORT));\n /* eslint new-cap:off */\n }\n\n auth.changePassword(\n name,\n password.old,\n password.new,\n (err, isUpdated): $NextFunctionVer => {\n if (_.isNull(err) === false) {\n return next(\n errorUtils.getCode(err.status, err.message) || errorUtils.getConflict(err.message)\n );\n }\n\n if (isUpdated) {\n return next(buildProfile(req.remote_user.name));\n }\n return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));\n }\n );\n } else if (_.isNil(tfa) === false) {\n return next(\n errorUtils.getCode(HTTP_STATUS.SERVICE_UNAVAILABLE, SUPPORT_ERRORS.TFA_DISABLED)\n );\n } else {\n return next(errorUtils.getCode(HTTP_STATUS.INTERNAL_ERROR, APP_ERROR.PROFILE_ERROR));\n }\n }\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"profile.js","names":["route","auth","config","buildProfile","name","tfa","email","email_verified","created","updated","cidr_whitelist","fullname","get","req","res","next","_","isNil","remote_user","status","HTTP_STATUS","UNAUTHORIZED","message","API_ERROR","MUST_BE_LOGGED","post","password","body","validatioUtils","validatePassword","new","serverSettings","passwordValidationRegex","errorUtils","getCode","PASSWORD_SHORT","changePassword","old","err","isUpdated","isNull","getConflict","getInternalError","INTERNAL_SERVER_ERROR","SERVICE_UNAVAILABLE","SUPPORT_ERRORS","TFA_DISABLED","INTERNAL_ERROR","APP_ERROR","PROFILE_ERROR"],"sources":["../../src/v1/profile.ts"],"sourcesContent":["import { Response, Router } from 'express';\nimport _ from 'lodash';\n\nimport { Auth } from '@verdaccio/auth';\nimport {\n API_ERROR,\n APP_ERROR,\n HTTP_STATUS,\n SUPPORT_ERRORS,\n errorUtils,\n validatioUtils,\n} from '@verdaccio/core';\nimport { Config } from '@verdaccio/types';\n\nimport { $NextFunctionVer, $RequestExtend } from '../../types/custom';\n\nexport interface Profile {\n tfa: boolean;\n name: string;\n email: string;\n email_verified: boolean;\n created: string;\n updated: string;\n cidr_whitelist: string[] | null;\n fullname: string;\n}\n\nexport default function (route: Router, auth: Auth, config: Config): void {\n function buildProfile(name: string): Profile {\n return {\n tfa: false,\n name,\n email: '',\n email_verified: false,\n created: '',\n updated: '',\n cidr_whitelist: null,\n fullname: '',\n };\n }\n\n route.get(\n '/-/npm/v1/user',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n if (_.isNil(req.remote_user.name) === false) {\n return next(buildProfile(req.remote_user.name));\n }\n\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n );\n\n route.post(\n '/-/npm/v1/user',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n if (_.isNil(req.remote_user.name)) {\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n\n const { password, tfa } = req.body;\n const { name } = req.remote_user;\n\n if (_.isNil(password) === false) {\n if (\n validatioUtils.validatePassword(\n password.new,\n config?.serverSettings?.passwordValidationRegex\n ) === false\n ) {\n /* eslint new-cap:off */\n return next(errorUtils.getCode(HTTP_STATUS.UNAUTHORIZED, API_ERROR.PASSWORD_SHORT));\n /* eslint new-cap:off */\n }\n\n auth.changePassword(\n name,\n password.old,\n password.new,\n (err, isUpdated): $NextFunctionVer => {\n if (_.isNull(err) === false) {\n return next(\n errorUtils.getCode(err.status, err.message) || errorUtils.getConflict(err.message)\n );\n }\n\n if (isUpdated) {\n return next(buildProfile(req.remote_user.name));\n }\n return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));\n }\n );\n } else if (_.isNil(tfa) === false) {\n return next(\n errorUtils.getCode(HTTP_STATUS.SERVICE_UNAVAILABLE, SUPPORT_ERRORS.TFA_DISABLED)\n );\n } else {\n return next(errorUtils.getCode(HTTP_STATUS.INTERNAL_ERROR, APP_ERROR.PROFILE_ERROR));\n }\n }\n );\n}\n"],"mappings":";;;;;;AACA;AAGA;AAOyB;AAgBV,kBAAUA,KAAa,EAAEC,IAAU,EAAEC,MAAc,EAAQ;EACxE,SAASC,YAAY,CAACC,IAAY,EAAW;IAC3C,OAAO;MACLC,GAAG,EAAE,KAAK;MACVD,IAAI;MACJE,KAAK,EAAE,EAAE;MACTC,cAAc,EAAE,KAAK;MACrBC,OAAO,EAAE,EAAE;MACXC,OAAO,EAAE,EAAE;MACXC,cAAc,EAAE,IAAI;MACpBC,QAAQ,EAAE;IACZ,CAAC;EACH;EAEAX,KAAK,CAACY,GAAG,CACP,gBAAgB,EAChB,UAAUC,GAAmB,EAAEC,GAAa,EAAEC,IAAsB,EAAQ;IAC1E,IAAIC,eAAC,CAACC,KAAK,CAACJ,GAAG,CAACK,WAAW,CAACd,IAAI,CAAC,KAAK,KAAK,EAAE;MAC3C,OAAOW,IAAI,CAACZ,YAAY,CAACU,GAAG,CAACK,WAAW,CAACd,IAAI,CAAC,CAAC;IACjD;IAEAU,GAAG,CAACK,MAAM,CAACC,iBAAW,CAACC,YAAY,CAAC;IACpC,OAAON,IAAI,CAAC;MACVO,OAAO,EAAEC,eAAS,CAACC;IACrB,CAAC,CAAC;EACJ,CAAC,CACF;EAEDxB,KAAK,CAACyB,IAAI,CACR,gBAAgB,EAChB,UAAUZ,GAAmB,EAAEC,GAAa,EAAEC,IAAsB,EAAQ;IAC1E,IAAIC,eAAC,CAACC,KAAK,CAACJ,GAAG,CAACK,WAAW,CAACd,IAAI,CAAC,EAAE;MACjCU,GAAG,CAACK,MAAM,CAACC,iBAAW,CAACC,YAAY,CAAC;MACpC,OAAON,IAAI,CAAC;QACVO,OAAO,EAAEC,eAAS,CAACC;MACrB,CAAC,CAAC;IACJ;IAEA,MAAM;MAAEE,QAAQ;MAAErB;IAAI,CAAC,GAAGQ,GAAG,CAACc,IAAI;IAClC,MAAM;MAAEvB;IAAK,CAAC,GAAGS,GAAG,CAACK,WAAW;IAEhC,IAAIF,eAAC,CAACC,KAAK,CAACS,QAAQ,CAAC,KAAK,KAAK,EAAE;MAAA;MAC/B,IACEE,oBAAc,CAACC,gBAAgB,CAC7BH,QAAQ,CAACI,GAAG,EACZ5B,MAAM,aAANA,MAAM,gDAANA,MAAM,CAAE6B,cAAc,0DAAtB,sBAAwBC,uBAAuB,CAChD,KAAK,KAAK,EACX;QACA;QACA,OAAOjB,IAAI,CAACkB,gBAAU,CAACC,OAAO,CAACd,iBAAW,CAACC,YAAY,EAAEE,eAAS,CAACY,cAAc,CAAC,CAAC;QACnF;MACF;;MAEAlC,IAAI,CAACmC,cAAc,CACjBhC,IAAI,EACJsB,QAAQ,CAACW,GAAG,EACZX,QAAQ,CAACI,GAAG,EACZ,CAACQ,GAAG,EAAEC,SAAS,KAAuB;QACpC,IAAIvB,eAAC,CAACwB,MAAM,CAACF,GAAG,CAAC,KAAK,KAAK,EAAE;UAC3B,OAAOvB,IAAI,CACTkB,gBAAU,CAACC,OAAO,CAACI,GAAG,CAACnB,MAAM,EAAEmB,GAAG,CAAChB,OAAO,CAAC,IAAIW,gBAAU,CAACQ,WAAW,CAACH,GAAG,CAAChB,OAAO,CAAC,CACnF;QACH;QAEA,IAAIiB,SAAS,EAAE;UACb,OAAOxB,IAAI,CAACZ,YAAY,CAACU,GAAG,CAACK,WAAW,CAACd,IAAI,CAAC,CAAC;QACjD;QACA,OAAOW,IAAI,CAACkB,gBAAU,CAACS,gBAAgB,CAACnB,eAAS,CAACoB,qBAAqB,CAAC,CAAC;MAC3E,CAAC,CACF;IACH,CAAC,MAAM,IAAI3B,eAAC,CAACC,KAAK,CAACZ,GAAG,CAAC,KAAK,KAAK,EAAE;MACjC,OAAOU,IAAI,CACTkB,gBAAU,CAACC,OAAO,CAACd,iBAAW,CAACwB,mBAAmB,EAAEC,oBAAc,CAACC,YAAY,CAAC,CACjF;IACH,CAAC,MAAM;MACL,OAAO/B,IAAI,CAACkB,gBAAU,CAACC,OAAO,CAACd,iBAAW,CAAC2B,cAAc,EAAEC,eAAS,CAACC,aAAa,CAAC,CAAC;IACtF;EACF,CAAC,CACF;AACH"}
|
package/build/v1/search.js
CHANGED
|
@@ -4,30 +4,23 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = _default;
|
|
7
|
-
|
|
8
7
|
var _debug = _interopRequireDefault(require("debug"));
|
|
9
|
-
|
|
10
8
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
11
|
-
|
|
12
9
|
var _core = require("@verdaccio/core");
|
|
13
|
-
|
|
14
10
|
var _logger = require("@verdaccio/logger");
|
|
15
|
-
|
|
16
11
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
-
|
|
18
12
|
const debug = (0, _debug.default)('verdaccio:api:search');
|
|
13
|
+
|
|
19
14
|
/**
|
|
20
15
|
* Endpoint for npm search v1
|
|
21
16
|
* Empty value
|
|
22
17
|
* - {"objects":[],"total":0,"time":"Sun Jul 25 2021 14:09:11 GMT+0000 (Coordinated Universal Time)"}
|
|
23
18
|
* req: 'GET /-/v1/search?text=react&size=20&frpom=0&quality=0.65&popularity=0.98&maintenance=0.5'
|
|
24
19
|
*/
|
|
25
|
-
|
|
26
20
|
function _default(route, auth, storage) {
|
|
27
21
|
function checkAccess(pkg, auth, remoteUser) {
|
|
28
22
|
return new Promise((resolve, reject) => {
|
|
29
23
|
var _pkg$package;
|
|
30
|
-
|
|
31
24
|
auth.allow_access({
|
|
32
25
|
packageName: pkg === null || pkg === void 0 ? void 0 : (_pkg$package = pkg.package) === null || _pkg$package === void 0 ? void 0 : _pkg$package.name
|
|
33
26
|
}, remoteUser, function (err, allowed) {
|
|
@@ -46,7 +39,6 @@ function _default(route, auth, storage) {
|
|
|
46
39
|
});
|
|
47
40
|
});
|
|
48
41
|
}
|
|
49
|
-
|
|
50
42
|
route.get('/-/v1/search', async (req, res, next) => {
|
|
51
43
|
const {
|
|
52
44
|
query,
|
|
@@ -61,7 +53,6 @@ function _default(route, auth, storage) {
|
|
|
61
53
|
});
|
|
62
54
|
size = parseInt(size, 10) || 20;
|
|
63
55
|
from = parseInt(from, 10) || 0;
|
|
64
|
-
|
|
65
56
|
try {
|
|
66
57
|
data = await storage.search({
|
|
67
58
|
query,
|
|
@@ -73,9 +64,7 @@ function _default(route, auth, storage) {
|
|
|
73
64
|
return checkAccess(pkgItem, auth, req.remote_user);
|
|
74
65
|
}));
|
|
75
66
|
const final = checkAccessPromises.filter(i => !_lodash.default.isNull(i)).slice(from, size);
|
|
76
|
-
|
|
77
67
|
_logger.logger.debug(`search results ${final === null || final === void 0 ? void 0 : final.length}`);
|
|
78
|
-
|
|
79
68
|
const response = {
|
|
80
69
|
objects: final,
|
|
81
70
|
total: final.length,
|
|
@@ -86,7 +75,6 @@ function _default(route, auth, storage) {
|
|
|
86
75
|
_logger.logger.error({
|
|
87
76
|
error
|
|
88
77
|
}, 'search endpoint has failed @{error.message}');
|
|
89
|
-
|
|
90
78
|
next(next);
|
|
91
79
|
return;
|
|
92
80
|
}
|
package/build/v1/search.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","names":["debug","buildDebug","route","auth","storage","checkAccess","pkg","remoteUser","Promise","resolve","reject","allow_access","packageName","package","name","err","allowed","status","String","match","get","req","res","next","query","url","size","from","map","k","data","abort","AbortController","socket","on","parseInt","search","checkAccessPromises","all","pkgItem","remote_user","final","filter","i","_","isNull","slice","logger","length","response","objects","total","time","Date","toUTCString","HTTP_STATUS","OK","json","error"],"sources":["../../src/v1/search.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport _ from 'lodash';\n\nimport { Auth } from '@verdaccio/auth';\nimport { HTTP_STATUS, searchUtils } from '@verdaccio/core';\nimport { logger } from '@verdaccio/logger';\nimport { Storage } from '@verdaccio/store';\nimport { Manifest } from '@verdaccio/types';\n\nconst debug = buildDebug('verdaccio:api:search');\n\n/**\n * Endpoint for npm search v1\n * Empty value\n * - {\"objects\":[],\"total\":0,\"time\":\"Sun Jul 25 2021 14:09:11 GMT+0000 (Coordinated Universal Time)\"}\n * req: 'GET /-/v1/search?text=react&size=20&frpom=0&quality=0.65&popularity=0.98&maintenance=0.5'\n */\nexport default function (route, auth: Auth, storage: Storage): void {\n function checkAccess(pkg: any, auth: any, remoteUser): Promise<Manifest | null> {\n return new Promise((resolve, reject) => {\n auth.allow_access({ packageName: pkg?.package?.name }, remoteUser, function (err, allowed) {\n if (err) {\n if (err.status && String(err.status).match(/^4\\d\\d$/)) {\n // auth plugin returns 4xx user error,\n // that's equivalent of !allowed basically\n allowed = false;\n return resolve(null);\n } else {\n reject(err);\n }\n } else {\n return resolve(allowed ? pkg : null);\n }\n });\n });\n }\n\n route.get('/-/v1/search', async (req, res, next) => {\n const { query, url } = req;\n let [size, from] = ['size', 'from'].map((k) => query[k]);\n let data;\n const abort = new AbortController();\n\n req.socket.on('close', function () {\n debug('search web aborted');\n abort.abort();\n });\n\n size = parseInt(size, 10) || 20;\n from = parseInt(from, 10) || 0;\n\n try {\n data = await storage.search({\n query,\n url,\n abort,\n });\n debug('stream finish');\n const checkAccessPromises: searchUtils.SearchItemPkg[] = await Promise.all(\n data.map((pkgItem) => {\n return checkAccess(pkgItem, auth, req.remote_user);\n })\n );\n\n const final: searchUtils.SearchItemPkg[] = checkAccessPromises\n .filter((i) => !_.isNull(i))\n .slice(from, size);\n logger.debug(`search results ${final?.length}`);\n\n const response: searchUtils.SearchResults = {\n objects: final,\n total: final.length,\n time: new Date().toUTCString(),\n };\n\n res.status(HTTP_STATUS.OK).json(response);\n } catch (error) {\n logger.error({ error }, 'search endpoint has failed @{error.message}');\n next(next);\n return;\n }\n });\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"search.js","names":["debug","buildDebug","route","auth","storage","checkAccess","pkg","remoteUser","Promise","resolve","reject","allow_access","packageName","package","name","err","allowed","status","String","match","get","req","res","next","query","url","size","from","map","k","data","abort","AbortController","socket","on","parseInt","search","checkAccessPromises","all","pkgItem","remote_user","final","filter","i","_","isNull","slice","logger","length","response","objects","total","time","Date","toUTCString","HTTP_STATUS","OK","json","error"],"sources":["../../src/v1/search.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport _ from 'lodash';\n\nimport { Auth } from '@verdaccio/auth';\nimport { HTTP_STATUS, searchUtils } from '@verdaccio/core';\nimport { logger } from '@verdaccio/logger';\nimport { Storage } from '@verdaccio/store';\nimport { Manifest } from '@verdaccio/types';\n\nconst debug = buildDebug('verdaccio:api:search');\n\n/**\n * Endpoint for npm search v1\n * Empty value\n * - {\"objects\":[],\"total\":0,\"time\":\"Sun Jul 25 2021 14:09:11 GMT+0000 (Coordinated Universal Time)\"}\n * req: 'GET /-/v1/search?text=react&size=20&frpom=0&quality=0.65&popularity=0.98&maintenance=0.5'\n */\nexport default function (route, auth: Auth, storage: Storage): void {\n function checkAccess(pkg: any, auth: any, remoteUser): Promise<Manifest | null> {\n return new Promise((resolve, reject) => {\n auth.allow_access({ packageName: pkg?.package?.name }, remoteUser, function (err, allowed) {\n if (err) {\n if (err.status && String(err.status).match(/^4\\d\\d$/)) {\n // auth plugin returns 4xx user error,\n // that's equivalent of !allowed basically\n allowed = false;\n return resolve(null);\n } else {\n reject(err);\n }\n } else {\n return resolve(allowed ? pkg : null);\n }\n });\n });\n }\n\n route.get('/-/v1/search', async (req, res, next) => {\n const { query, url } = req;\n let [size, from] = ['size', 'from'].map((k) => query[k]);\n let data;\n const abort = new AbortController();\n\n req.socket.on('close', function () {\n debug('search web aborted');\n abort.abort();\n });\n\n size = parseInt(size, 10) || 20;\n from = parseInt(from, 10) || 0;\n\n try {\n data = await storage.search({\n query,\n url,\n abort,\n });\n debug('stream finish');\n const checkAccessPromises: searchUtils.SearchItemPkg[] = await Promise.all(\n data.map((pkgItem) => {\n return checkAccess(pkgItem, auth, req.remote_user);\n })\n );\n\n const final: searchUtils.SearchItemPkg[] = checkAccessPromises\n .filter((i) => !_.isNull(i))\n .slice(from, size);\n logger.debug(`search results ${final?.length}`);\n\n const response: searchUtils.SearchResults = {\n objects: final,\n total: final.length,\n time: new Date().toUTCString(),\n };\n\n res.status(HTTP_STATUS.OK).json(response);\n } catch (error) {\n logger.error({ error }, 'search endpoint has failed @{error.message}');\n next(next);\n return;\n }\n });\n}\n"],"mappings":"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"}
|
package/build/v1/token.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Router } from 'express';
|
|
|
2
2
|
import { Auth } from '@verdaccio/auth';
|
|
3
3
|
import { Storage } from '@verdaccio/store';
|
|
4
4
|
import { Config, Token } from '@verdaccio/types';
|
|
5
|
-
export
|
|
5
|
+
export type NormalizeToken = Token & {
|
|
6
6
|
created: string;
|
|
7
7
|
};
|
|
8
8
|
export default function (route: Router, auth: Auth, storage: Storage, config: Config): void;
|
package/build/v1/token.js
CHANGED
|
@@ -4,60 +4,48 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = _default;
|
|
7
|
-
|
|
8
7
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
9
|
-
|
|
10
8
|
var _auth = require("@verdaccio/auth");
|
|
11
|
-
|
|
12
9
|
var _core = require("@verdaccio/core");
|
|
13
|
-
|
|
14
10
|
var _logger = require("@verdaccio/logger");
|
|
15
|
-
|
|
16
11
|
var _utils = require("@verdaccio/utils");
|
|
17
|
-
|
|
18
12
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
|
-
|
|
20
13
|
function normalizeToken(token) {
|
|
21
|
-
return {
|
|
14
|
+
return {
|
|
15
|
+
...token,
|
|
22
16
|
created: new Date(token.created).toISOString()
|
|
23
17
|
};
|
|
24
|
-
}
|
|
25
|
-
|
|
18
|
+
}
|
|
26
19
|
|
|
20
|
+
// https://github.com/npm/npm-profile/blob/latest/lib/index.js
|
|
27
21
|
function _default(route, auth, storage, config) {
|
|
28
22
|
route.get('/-/npm/v1/tokens', async function (req, res, next) {
|
|
29
23
|
const {
|
|
30
24
|
name
|
|
31
25
|
} = req.remote_user;
|
|
32
|
-
|
|
33
26
|
if (_lodash.default.isNil(name) === false) {
|
|
34
27
|
try {
|
|
35
28
|
const tokens = await storage.readTokens({
|
|
36
29
|
user: name
|
|
37
30
|
});
|
|
38
31
|
const totalTokens = tokens.length;
|
|
39
|
-
|
|
40
32
|
_logger.logger.debug({
|
|
41
33
|
totalTokens
|
|
42
34
|
}, 'token list retrieved: @{totalTokens}');
|
|
43
|
-
|
|
44
35
|
res.status(_core.HTTP_STATUS.OK);
|
|
45
36
|
return next({
|
|
46
37
|
objects: tokens.map(normalizeToken),
|
|
47
38
|
urls: {
|
|
48
39
|
next: '' // TODO: pagination?
|
|
49
|
-
|
|
50
40
|
}
|
|
51
41
|
});
|
|
52
42
|
} catch (error) {
|
|
53
43
|
_logger.logger.error({
|
|
54
44
|
error: error.msg
|
|
55
45
|
}, 'token list has failed: @{error}');
|
|
56
|
-
|
|
57
46
|
return next(_core.errorUtils.getCode(_core.HTTP_STATUS.INTERNAL_ERROR, error.message));
|
|
58
47
|
}
|
|
59
48
|
}
|
|
60
|
-
|
|
61
49
|
return next(_core.errorUtils.getUnauthorized());
|
|
62
50
|
});
|
|
63
51
|
route.post('/-/npm/v1/tokens', function (req, res, next) {
|
|
@@ -69,40 +57,33 @@ function _default(route, auth, storage, config) {
|
|
|
69
57
|
const {
|
|
70
58
|
name
|
|
71
59
|
} = req.remote_user;
|
|
72
|
-
|
|
73
60
|
if (!_lodash.default.isBoolean(readonly) || !_lodash.default.isArray(cidr_whitelist)) {
|
|
74
61
|
return next(_core.errorUtils.getCode(_core.HTTP_STATUS.BAD_DATA, _core.SUPPORT_ERRORS.PARAMETERS_NOT_VALID));
|
|
75
62
|
}
|
|
76
|
-
|
|
77
63
|
auth.authenticate(name, password, async (err, user) => {
|
|
78
64
|
if (err) {
|
|
79
65
|
const errorCode = err.message ? _core.HTTP_STATUS.UNAUTHORIZED : _core.HTTP_STATUS.INTERNAL_ERROR;
|
|
80
66
|
return next(_core.errorUtils.getCode(errorCode, err.message));
|
|
81
67
|
}
|
|
82
|
-
|
|
83
68
|
req.remote_user = user;
|
|
84
|
-
|
|
85
69
|
if (!_lodash.default.isFunction(storage.saveToken)) {
|
|
86
70
|
return next(_core.errorUtils.getCode(_core.HTTP_STATUS.NOT_IMPLEMENTED, _core.SUPPORT_ERRORS.STORAGE_NOT_IMPLEMENT));
|
|
87
71
|
}
|
|
88
|
-
|
|
89
72
|
try {
|
|
90
73
|
const token = await (0, _auth.getApiToken)(auth, config, user, password);
|
|
91
|
-
|
|
92
74
|
if (!token) {
|
|
93
75
|
throw _core.errorUtils.getInternalError();
|
|
94
76
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
77
|
+
const key = (0, _utils.stringToMD5)(token);
|
|
78
|
+
// TODO: use a utility here
|
|
98
79
|
const maskedToken = (0, _utils.mask)(token, 5);
|
|
99
80
|
const created = new Date().getTime();
|
|
81
|
+
|
|
100
82
|
/**
|
|
101
83
|
* cidr_whitelist: is not being used, we pass it through
|
|
102
84
|
* token: we do not store the real token (it is generated once and retrieved
|
|
103
85
|
* to the user), just a mask of it.
|
|
104
86
|
*/
|
|
105
|
-
|
|
106
87
|
const saveToken = {
|
|
107
88
|
user: name,
|
|
108
89
|
token: maskedToken,
|
|
@@ -112,12 +93,10 @@ function _default(route, auth, storage, config) {
|
|
|
112
93
|
created
|
|
113
94
|
};
|
|
114
95
|
await storage.saveToken(saveToken);
|
|
115
|
-
|
|
116
96
|
_logger.logger.debug({
|
|
117
97
|
key,
|
|
118
98
|
name
|
|
119
99
|
}, 'token @{key} was created for user @{name}');
|
|
120
|
-
|
|
121
100
|
res.set(_core.HEADERS.CACHE_CONTROL, 'no-cache, no-store');
|
|
122
101
|
return next(normalizeToken({
|
|
123
102
|
token,
|
|
@@ -131,7 +110,6 @@ function _default(route, auth, storage, config) {
|
|
|
131
110
|
_logger.logger.error({
|
|
132
111
|
error: error.msg
|
|
133
112
|
}, 'token creation has failed: @{error}');
|
|
134
|
-
|
|
135
113
|
return next(_core.errorUtils.getInternalError(error.message));
|
|
136
114
|
}
|
|
137
115
|
});
|
|
@@ -145,30 +123,24 @@ function _default(route, auth, storage, config) {
|
|
|
145
123
|
const {
|
|
146
124
|
name
|
|
147
125
|
} = req.remote_user;
|
|
148
|
-
|
|
149
126
|
if (_lodash.default.isNil(name) === false) {
|
|
150
127
|
_logger.logger.debug({
|
|
151
128
|
name
|
|
152
129
|
}, '@{name} has requested remove a token');
|
|
153
|
-
|
|
154
130
|
try {
|
|
155
131
|
await storage.deleteToken(name, tokenKey);
|
|
156
|
-
|
|
157
132
|
_logger.logger.info({
|
|
158
133
|
tokenKey,
|
|
159
134
|
name
|
|
160
135
|
}, 'token id @{tokenKey} was revoked for user @{name}');
|
|
161
|
-
|
|
162
136
|
return next({});
|
|
163
137
|
} catch (error) {
|
|
164
138
|
_logger.logger.error({
|
|
165
139
|
error: error.msg
|
|
166
140
|
}, 'token creation has failed: @{error}');
|
|
167
|
-
|
|
168
141
|
return next(_core.errorUtils.getCode(_core.HTTP_STATUS.INTERNAL_ERROR, error.message));
|
|
169
142
|
}
|
|
170
143
|
}
|
|
171
|
-
|
|
172
144
|
return next(_core.errorUtils.getUnauthorized());
|
|
173
145
|
});
|
|
174
146
|
}
|
package/build/v1/token.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.js","names":["normalizeToken","token","created","Date","toISOString","route","auth","storage","config","get","req","res","next","name","remote_user","_","isNil","tokens","readTokens","user","totalTokens","length","logger","debug","status","HTTP_STATUS","OK","objects","map","urls","error","msg","errorUtils","getCode","INTERNAL_ERROR","message","getUnauthorized","post","password","readonly","cidr_whitelist","body","isBoolean","isArray","BAD_DATA","SUPPORT_ERRORS","PARAMETERS_NOT_VALID","authenticate","err","errorCode","UNAUTHORIZED","isFunction","saveToken","NOT_IMPLEMENTED","STORAGE_NOT_IMPLEMENT","getApiToken","getInternalError","key","stringToMD5","maskedToken","mask","getTime","cidr","set","HEADERS","CACHE_CONTROL","delete","params","tokenKey","deleteToken","info"],"sources":["../../src/v1/token.ts"],"sourcesContent":["import { Response, Router } from 'express';\nimport _ from 'lodash';\n\nimport { getApiToken } from '@verdaccio/auth';\nimport { Auth } from '@verdaccio/auth';\nimport { HEADERS, HTTP_STATUS, SUPPORT_ERRORS, errorUtils } from '@verdaccio/core';\nimport { logger } from '@verdaccio/logger';\nimport { Storage } from '@verdaccio/store';\nimport { Config, RemoteUser, Token } from '@verdaccio/types';\nimport { mask, stringToMD5 } from '@verdaccio/utils';\n\nimport { $NextFunctionVer, $RequestExtend } from '../../types/custom';\n\nexport type NormalizeToken = Token & {\n created: string;\n};\n\nfunction normalizeToken(token: Token): NormalizeToken {\n return {\n ...token,\n created: new Date(token.created).toISOString(),\n };\n}\n\n// https://github.com/npm/npm-profile/blob/latest/lib/index.js\nexport default function (route: Router, auth: Auth, storage: Storage, config: Config): void {\n route.get(\n '/-/npm/v1/tokens',\n async function (req: $RequestExtend, res: Response, next: $NextFunctionVer) {\n const { name } = req.remote_user;\n\n if (_.isNil(name) === false) {\n try {\n const tokens = await storage.readTokens({ user: name });\n const totalTokens = tokens.length;\n logger.debug({ totalTokens }, 'token list retrieved: @{totalTokens}');\n\n res.status(HTTP_STATUS.OK);\n return next({\n objects: tokens.map(normalizeToken),\n urls: {\n next: '', // TODO: pagination?\n },\n });\n } catch (error: any) {\n logger.error({ error: error.msg }, 'token list has failed: @{error}');\n return next(errorUtils.getCode(HTTP_STATUS.INTERNAL_ERROR, error.message));\n }\n }\n return next(errorUtils.getUnauthorized());\n }\n );\n\n route.post(\n '/-/npm/v1/tokens',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer) {\n const { password, readonly, cidr_whitelist } = req.body;\n const { name } = req.remote_user;\n\n if (!_.isBoolean(readonly) || !_.isArray(cidr_whitelist)) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_DATA, SUPPORT_ERRORS.PARAMETERS_NOT_VALID));\n }\n\n auth.authenticate(name, password, async (err, user?: RemoteUser) => {\n if (err) {\n const errorCode = err.message ? HTTP_STATUS.UNAUTHORIZED : HTTP_STATUS.INTERNAL_ERROR;\n return next(errorUtils.getCode(errorCode, err.message));\n }\n\n req.remote_user = user;\n\n if (!_.isFunction(storage.saveToken)) {\n return next(\n errorUtils.getCode(HTTP_STATUS.NOT_IMPLEMENTED, SUPPORT_ERRORS.STORAGE_NOT_IMPLEMENT)\n );\n }\n\n try {\n const token = await getApiToken(auth, config, user as RemoteUser, password);\n if (!token) {\n throw errorUtils.getInternalError();\n }\n\n const key = stringToMD5(token);\n // TODO: use a utility here\n const maskedToken = mask(token, 5);\n const created = new Date().getTime();\n\n /**\n * cidr_whitelist: is not being used, we pass it through\n * token: we do not store the real token (it is generated once and retrieved\n * to the user), just a mask of it.\n */\n const saveToken: Token = {\n user: name,\n token: maskedToken,\n key,\n cidr: cidr_whitelist,\n readonly,\n created,\n };\n\n await storage.saveToken(saveToken);\n logger.debug({ key, name }, 'token @{key} was created for user @{name}');\n res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');\n return next(\n normalizeToken({\n token,\n user: name,\n key: saveToken.key,\n cidr: cidr_whitelist,\n readonly,\n created: saveToken.created,\n })\n );\n } catch (error: any) {\n logger.error({ error: error.msg }, 'token creation has failed: @{error}');\n return next(errorUtils.getInternalError(error.message));\n }\n });\n }\n );\n\n route.delete(\n '/-/npm/v1/tokens/token/:tokenKey',\n async (req: $RequestExtend, res: Response, next: $NextFunctionVer) => {\n const {\n params: { tokenKey },\n } = req;\n const { name } = req.remote_user;\n\n if (_.isNil(name) === false) {\n logger.debug({ name }, '@{name} has requested remove a token');\n try {\n await storage.deleteToken(name, tokenKey);\n logger.info({ tokenKey, name }, 'token id @{tokenKey} was revoked for user @{name}');\n return next({});\n } catch (error: any) {\n logger.error({ error: error.msg }, 'token creation has failed: @{error}');\n return next(errorUtils.getCode(HTTP_STATUS.INTERNAL_ERROR, error.message));\n }\n }\n return next(errorUtils.getUnauthorized());\n }\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"token.js","names":["normalizeToken","token","created","Date","toISOString","route","auth","storage","config","get","req","res","next","name","remote_user","_","isNil","tokens","readTokens","user","totalTokens","length","logger","debug","status","HTTP_STATUS","OK","objects","map","urls","error","msg","errorUtils","getCode","INTERNAL_ERROR","message","getUnauthorized","post","password","readonly","cidr_whitelist","body","isBoolean","isArray","BAD_DATA","SUPPORT_ERRORS","PARAMETERS_NOT_VALID","authenticate","err","errorCode","UNAUTHORIZED","isFunction","saveToken","NOT_IMPLEMENTED","STORAGE_NOT_IMPLEMENT","getApiToken","getInternalError","key","stringToMD5","maskedToken","mask","getTime","cidr","set","HEADERS","CACHE_CONTROL","delete","params","tokenKey","deleteToken","info"],"sources":["../../src/v1/token.ts"],"sourcesContent":["import { Response, Router } from 'express';\nimport _ from 'lodash';\n\nimport { getApiToken } from '@verdaccio/auth';\nimport { Auth } from '@verdaccio/auth';\nimport { HEADERS, HTTP_STATUS, SUPPORT_ERRORS, errorUtils } from '@verdaccio/core';\nimport { logger } from '@verdaccio/logger';\nimport { Storage } from '@verdaccio/store';\nimport { Config, RemoteUser, Token } from '@verdaccio/types';\nimport { mask, stringToMD5 } from '@verdaccio/utils';\n\nimport { $NextFunctionVer, $RequestExtend } from '../../types/custom';\n\nexport type NormalizeToken = Token & {\n created: string;\n};\n\nfunction normalizeToken(token: Token): NormalizeToken {\n return {\n ...token,\n created: new Date(token.created).toISOString(),\n };\n}\n\n// https://github.com/npm/npm-profile/blob/latest/lib/index.js\nexport default function (route: Router, auth: Auth, storage: Storage, config: Config): void {\n route.get(\n '/-/npm/v1/tokens',\n async function (req: $RequestExtend, res: Response, next: $NextFunctionVer) {\n const { name } = req.remote_user;\n\n if (_.isNil(name) === false) {\n try {\n const tokens = await storage.readTokens({ user: name });\n const totalTokens = tokens.length;\n logger.debug({ totalTokens }, 'token list retrieved: @{totalTokens}');\n\n res.status(HTTP_STATUS.OK);\n return next({\n objects: tokens.map(normalizeToken),\n urls: {\n next: '', // TODO: pagination?\n },\n });\n } catch (error: any) {\n logger.error({ error: error.msg }, 'token list has failed: @{error}');\n return next(errorUtils.getCode(HTTP_STATUS.INTERNAL_ERROR, error.message));\n }\n }\n return next(errorUtils.getUnauthorized());\n }\n );\n\n route.post(\n '/-/npm/v1/tokens',\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer) {\n const { password, readonly, cidr_whitelist } = req.body;\n const { name } = req.remote_user;\n\n if (!_.isBoolean(readonly) || !_.isArray(cidr_whitelist)) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_DATA, SUPPORT_ERRORS.PARAMETERS_NOT_VALID));\n }\n\n auth.authenticate(name, password, async (err, user?: RemoteUser) => {\n if (err) {\n const errorCode = err.message ? HTTP_STATUS.UNAUTHORIZED : HTTP_STATUS.INTERNAL_ERROR;\n return next(errorUtils.getCode(errorCode, err.message));\n }\n\n req.remote_user = user;\n\n if (!_.isFunction(storage.saveToken)) {\n return next(\n errorUtils.getCode(HTTP_STATUS.NOT_IMPLEMENTED, SUPPORT_ERRORS.STORAGE_NOT_IMPLEMENT)\n );\n }\n\n try {\n const token = await getApiToken(auth, config, user as RemoteUser, password);\n if (!token) {\n throw errorUtils.getInternalError();\n }\n\n const key = stringToMD5(token);\n // TODO: use a utility here\n const maskedToken = mask(token, 5);\n const created = new Date().getTime();\n\n /**\n * cidr_whitelist: is not being used, we pass it through\n * token: we do not store the real token (it is generated once and retrieved\n * to the user), just a mask of it.\n */\n const saveToken: Token = {\n user: name,\n token: maskedToken,\n key,\n cidr: cidr_whitelist,\n readonly,\n created,\n };\n\n await storage.saveToken(saveToken);\n logger.debug({ key, name }, 'token @{key} was created for user @{name}');\n res.set(HEADERS.CACHE_CONTROL, 'no-cache, no-store');\n return next(\n normalizeToken({\n token,\n user: name,\n key: saveToken.key,\n cidr: cidr_whitelist,\n readonly,\n created: saveToken.created,\n })\n );\n } catch (error: any) {\n logger.error({ error: error.msg }, 'token creation has failed: @{error}');\n return next(errorUtils.getInternalError(error.message));\n }\n });\n }\n );\n\n route.delete(\n '/-/npm/v1/tokens/token/:tokenKey',\n async (req: $RequestExtend, res: Response, next: $NextFunctionVer) => {\n const {\n params: { tokenKey },\n } = req;\n const { name } = req.remote_user;\n\n if (_.isNil(name) === false) {\n logger.debug({ name }, '@{name} has requested remove a token');\n try {\n await storage.deleteToken(name, tokenKey);\n logger.info({ tokenKey, name }, 'token id @{tokenKey} was revoked for user @{name}');\n return next({});\n } catch (error: any) {\n logger.error({ error: error.msg }, 'token creation has failed: @{error}');\n return next(errorUtils.getCode(HTTP_STATUS.INTERNAL_ERROR, error.message));\n }\n }\n return next(errorUtils.getUnauthorized());\n }\n );\n}\n"],"mappings":"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"}
|