@verdaccio/middleware 6.0.0-6-next.35 → 6.0.0-6-next.37
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 +16 -0
- package/build/middlewares/allow.d.ts +4 -1
- package/build/middlewares/allow.js +15 -3
- package/build/middlewares/allow.js.map +1 -1
- package/build/middlewares/error.d.ts +2 -2
- package/build/middlewares/error.js +10 -10
- package/build/middlewares/error.js.map +1 -1
- package/build/middlewares/log.d.ts +1 -1
- package/build/middlewares/log.js +81 -80
- package/build/middlewares/log.js.map +1 -1
- package/jest.config.js +2 -2
- package/package.json +6 -7
- package/src/middlewares/allow.ts +15 -3
- package/src/middlewares/error.ts +63 -62
- package/src/middlewares/log.ts +78 -78
- package/test/allow.spec.ts +36 -21
- package/test/log.spec.ts +2 -2
- package/tsconfig.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @verdaccio/middleware
|
|
2
2
|
|
|
3
|
+
## 6.0.0-6-next.37
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- fa274ee4: chore: bumb up package
|
|
8
|
+
- @verdaccio/core@6.0.0-6-next.58
|
|
9
|
+
- @verdaccio/utils@6.0.0-6-next.26
|
|
10
|
+
|
|
11
|
+
## 6.0.0-6-next.36
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 9943e2b1: fix: extract logger from middleware
|
|
16
|
+
- @verdaccio/core@6.0.0-6-next.57
|
|
17
|
+
- @verdaccio/utils@6.0.0-6-next.25
|
|
18
|
+
|
|
3
19
|
## 6.0.0-6-next.35
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
|
@@ -5,16 +5,24 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.allow = allow;
|
|
7
7
|
var _core = require("@verdaccio/core");
|
|
8
|
-
var _logger = require("@verdaccio/logger");
|
|
9
8
|
var _utils = require("@verdaccio/utils");
|
|
10
|
-
function allow(auth
|
|
9
|
+
function allow(auth, options = {
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
11
|
+
beforeAll: (_a, _b) => {},
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
13
|
+
afterAll: (_a, _b) => {}
|
|
14
|
+
}) {
|
|
15
|
+
const {
|
|
16
|
+
beforeAll,
|
|
17
|
+
afterAll
|
|
18
|
+
} = options;
|
|
11
19
|
return function (action) {
|
|
12
20
|
return function (req, res, next) {
|
|
13
21
|
req.pause();
|
|
14
22
|
const packageName = req.params.scope ? `@${req.params.scope}/${req.params.package}` : req.params.package;
|
|
15
23
|
const packageVersion = req.params.filename ? (0, _utils.getVersionFromTarball)(req.params.filename) : undefined;
|
|
16
24
|
const remote = req.remote_user;
|
|
17
|
-
|
|
25
|
+
beforeAll === null || beforeAll === void 0 ? void 0 : beforeAll({
|
|
18
26
|
action,
|
|
19
27
|
user: remote === null || remote === void 0 ? void 0 : remote.name
|
|
20
28
|
}, `[middleware/allow][@{action}] allow for @{user}`);
|
|
@@ -26,6 +34,10 @@ function allow(auth) {
|
|
|
26
34
|
if (error) {
|
|
27
35
|
next(error);
|
|
28
36
|
} else if (allowed) {
|
|
37
|
+
afterAll === null || afterAll === void 0 ? void 0 : afterAll({
|
|
38
|
+
action,
|
|
39
|
+
user: remote === null || remote === void 0 ? void 0 : remote.name
|
|
40
|
+
}, `[middleware/allow][@{action}] allowed for @{user}`);
|
|
29
41
|
next();
|
|
30
42
|
} else {
|
|
31
43
|
// last plugin (that's our built-in one) returns either
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"allow.js","names":["allow","auth","action","req","res","next","pause","packageName","params","scope","package","packageVersion","filename","getVersionFromTarball","undefined","remote","remote_user","
|
|
1
|
+
{"version":3,"file":"allow.js","names":["allow","auth","options","beforeAll","_a","_b","afterAll","action","req","res","next","pause","packageName","params","scope","package","packageVersion","filename","getVersionFromTarball","undefined","remote","remote_user","user","name","error","allowed","resume","errorUtils","getInternalError","API_ERROR","PLUGIN_ERROR"],"sources":["../../src/middlewares/allow.ts"],"sourcesContent":["import { API_ERROR, errorUtils } from '@verdaccio/core';\nimport { getVersionFromTarball } from '@verdaccio/utils';\n\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';\n\nexport function allow<T>(\n auth: T,\n options = {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n beforeAll: (_a: any, _b: any) => {},\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n afterAll: (_a: any, _b: any) => {},\n }\n): Function {\n const { beforeAll, afterAll } = options;\n return function (action: string): Function {\n return function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {\n req.pause();\n const packageName = req.params.scope\n ? `@${req.params.scope}/${req.params.package}`\n : req.params.package;\n const packageVersion = req.params.filename\n ? getVersionFromTarball(req.params.filename)\n : undefined;\n const remote = req.remote_user;\n beforeAll?.(\n { action, user: remote?.name },\n `[middleware/allow][@{action}] allow for @{user}`\n );\n auth['allow_' + action](\n { packageName, packageVersion },\n remote,\n function (error, allowed): void {\n req.resume();\n if (error) {\n next(error);\n } else if (allowed) {\n afterAll?.(\n { action, user: remote?.name },\n `[middleware/allow][@{action}] allowed for @{user}`\n );\n next();\n } else {\n // last plugin (that's our built-in one) returns either\n // cb(err) or cb(null, true), so this should never happen\n throw errorUtils.getInternalError(API_ERROR.PLUGIN_ERROR);\n }\n }\n );\n };\n };\n}\n"],"mappings":";;;;;;AAAA;AACA;AAIO,SAASA,KAAK,CACnBC,IAAO,EACPC,OAAO,GAAG;EACR;EACAC,SAAS,EAAE,CAACC,EAAO,EAAEC,EAAO,KAAK,CAAC,CAAC;EACnC;EACAC,QAAQ,EAAE,CAACF,EAAO,EAAEC,EAAO,KAAK,CAAC;AACnC,CAAC,EACS;EACV,MAAM;IAAEF,SAAS;IAAEG;EAAS,CAAC,GAAGJ,OAAO;EACvC,OAAO,UAAUK,MAAc,EAAY;IACzC,OAAO,UAAUC,GAAmB,EAAEC,GAAoB,EAAEC,IAAsB,EAAQ;MACxFF,GAAG,CAACG,KAAK,EAAE;MACX,MAAMC,WAAW,GAAGJ,GAAG,CAACK,MAAM,CAACC,KAAK,GAC/B,IAAGN,GAAG,CAACK,MAAM,CAACC,KAAM,IAAGN,GAAG,CAACK,MAAM,CAACE,OAAQ,EAAC,GAC5CP,GAAG,CAACK,MAAM,CAACE,OAAO;MACtB,MAAMC,cAAc,GAAGR,GAAG,CAACK,MAAM,CAACI,QAAQ,GACtC,IAAAC,4BAAqB,EAACV,GAAG,CAACK,MAAM,CAACI,QAAQ,CAAC,GAC1CE,SAAS;MACb,MAAMC,MAAM,GAAGZ,GAAG,CAACa,WAAW;MAC9BlB,SAAS,aAATA,SAAS,uBAATA,SAAS,CACP;QAAEI,MAAM;QAAEe,IAAI,EAAEF,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEG;MAAK,CAAC,EAC7B,iDAAgD,CAClD;MACDtB,IAAI,CAAC,QAAQ,GAAGM,MAAM,CAAC,CACrB;QAAEK,WAAW;QAAEI;MAAe,CAAC,EAC/BI,MAAM,EACN,UAAUI,KAAK,EAAEC,OAAO,EAAQ;QAC9BjB,GAAG,CAACkB,MAAM,EAAE;QACZ,IAAIF,KAAK,EAAE;UACTd,IAAI,CAACc,KAAK,CAAC;QACb,CAAC,MAAM,IAAIC,OAAO,EAAE;UAClBnB,QAAQ,aAARA,QAAQ,uBAARA,QAAQ,CACN;YAAEC,MAAM;YAAEe,IAAI,EAAEF,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEG;UAAK,CAAC,EAC7B,mDAAkD,CACpD;UACDb,IAAI,EAAE;QACR,CAAC,MAAM;UACL;UACA;UACA,MAAMiB,gBAAU,CAACC,gBAAgB,CAACC,eAAS,CAACC,YAAY,CAAC;QAC3D;MACF,CAAC,CACF;IACH,CAAC;EACH,CAAC;AACH"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { HttpError } from 'http-errors';
|
|
2
2
|
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';
|
|
3
|
-
export declare
|
|
4
|
-
export declare
|
|
3
|
+
export declare const handleError: (logger: any) => (err: HttpError, req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) => any;
|
|
4
|
+
export declare const errorReportingMiddleware: (logger: any) => (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) => void;
|
|
@@ -3,15 +3,13 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.errorReportingMiddleware =
|
|
7
|
-
exports.handleError = handleError;
|
|
6
|
+
exports.handleError = exports.errorReportingMiddleware = void 0;
|
|
8
7
|
var _debug = _interopRequireDefault(require("debug"));
|
|
9
8
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
10
9
|
var _core = require("@verdaccio/core");
|
|
11
|
-
var _logger = require("@verdaccio/logger");
|
|
12
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
11
|
const debug = (0, _debug.default)('verdaccio:middleware:error');
|
|
14
|
-
function handleError(err, req, res, next) {
|
|
12
|
+
const handleError = logger => function handleError(err, req, res, next) {
|
|
15
13
|
debug('error handler init');
|
|
16
14
|
if (_lodash.default.isError(err)) {
|
|
17
15
|
debug('is native error');
|
|
@@ -22,7 +20,7 @@ function handleError(err, req, res, next) {
|
|
|
22
20
|
debug('is locals error report ref');
|
|
23
21
|
// in case of very early error this middleware may not be loaded before error is generated
|
|
24
22
|
// fixing that
|
|
25
|
-
errorReportingMiddleware(req, res, _lodash.default.noop);
|
|
23
|
+
errorReportingMiddleware(logger)(req, res, _lodash.default.noop);
|
|
26
24
|
}
|
|
27
25
|
debug('set locals error report ref');
|
|
28
26
|
res.locals.report_error(err);
|
|
@@ -31,10 +29,11 @@ function handleError(err, req, res, next) {
|
|
|
31
29
|
debug('no error to report, jump next layer');
|
|
32
30
|
return next(err);
|
|
33
31
|
}
|
|
34
|
-
}
|
|
32
|
+
};
|
|
35
33
|
|
|
36
34
|
// Middleware
|
|
37
|
-
|
|
35
|
+
exports.handleError = handleError;
|
|
36
|
+
const errorReportingMiddleware = logger => function errorReportingMiddleware(req, res, next) {
|
|
38
37
|
debug('error report middleware');
|
|
39
38
|
res.locals.report_error = res.locals.report_error || function (err) {
|
|
40
39
|
if (err.status && err.status >= _core.HTTP_STATUS.BAD_REQUEST && err.status < 600) {
|
|
@@ -49,12 +48,12 @@ function errorReportingMiddleware(req, res, next) {
|
|
|
49
48
|
}
|
|
50
49
|
} else {
|
|
51
50
|
debug('is error < 409 %o', err === null || err === void 0 ? void 0 : err.status);
|
|
52
|
-
|
|
51
|
+
logger.error({
|
|
53
52
|
err: err
|
|
54
53
|
}, 'unexpected error: @{!err.message}\n@{err.stack}');
|
|
55
54
|
if (!res.status || !res.send) {
|
|
56
55
|
// TODO: decide which debug keep
|
|
57
|
-
|
|
56
|
+
logger.error('this is an error in express.js, please report this');
|
|
58
57
|
debug('this is an error in express.js, please report this, destroy response %o', err);
|
|
59
58
|
res.destroy();
|
|
60
59
|
} else if (!res.headersSent) {
|
|
@@ -71,5 +70,6 @@ function errorReportingMiddleware(req, res, next) {
|
|
|
71
70
|
};
|
|
72
71
|
debug('error report middleware next()');
|
|
73
72
|
next();
|
|
74
|
-
}
|
|
73
|
+
};
|
|
74
|
+
exports.errorReportingMiddleware = errorReportingMiddleware;
|
|
75
75
|
//# sourceMappingURL=error.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","names":["debug","buildDebug","handleError","err","req","res","next","_","isError","code","statusCode","HTTP_STATUS","NOT_MODIFIED","isFunction","locals","report_error","errorReportingMiddleware","noop","status","BAD_REQUEST","isNil","headersSent","message","error","API_ERROR","UNKNOWN_ERROR","
|
|
1
|
+
{"version":3,"file":"error.js","names":["debug","buildDebug","handleError","logger","err","req","res","next","_","isError","code","statusCode","HTTP_STATUS","NOT_MODIFIED","isFunction","locals","report_error","errorReportingMiddleware","noop","status","BAD_REQUEST","isNil","headersSent","message","error","API_ERROR","UNKNOWN_ERROR","send","destroy","INTERNAL_ERROR","INTERNAL_SERVER_ERROR"],"sources":["../../src/middlewares/error.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { HttpError } from 'http-errors';\nimport _ from 'lodash';\n\nimport { API_ERROR, HTTP_STATUS, VerdaccioError } from '@verdaccio/core';\n\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';\n\nconst debug = buildDebug('verdaccio:middleware:error');\n\nexport const handleError = (logger) =>\n function handleError(\n err: HttpError,\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n ) {\n debug('error handler init');\n if (_.isError(err)) {\n debug('is native error');\n if (err.code === 'ECONNABORT' && res.statusCode === HTTP_STATUS.NOT_MODIFIED) {\n return next();\n }\n if (_.isFunction(res.locals.report_error) === false) {\n debug('is locals error report ref');\n // in case of very early error this middleware may not be loaded before error is generated\n // fixing that\n errorReportingMiddleware(logger)(req, res, _.noop);\n }\n debug('set locals error report ref');\n res.locals.report_error(err);\n } else {\n // Fall to Middleware.final\n debug('no error to report, jump next layer');\n return next(err);\n }\n };\n\n// Middleware\nexport const errorReportingMiddleware = (logger) =>\n function errorReportingMiddleware(\n req: $RequestExtend,\n res: $ResponseExtend,\n next: $NextFunctionVer\n ): void {\n debug('error report middleware');\n res.locals.report_error =\n res.locals.report_error ||\n function (err: VerdaccioError): void {\n if (err.status && err.status >= HTTP_STATUS.BAD_REQUEST && err.status < 600) {\n debug('is error > 409 %o', err?.status);\n if (_.isNil(res.headersSent) === false) {\n debug('send status %o', err?.status);\n res.status(err.status);\n debug('next layer %o', err?.message);\n next({ error: err.message || API_ERROR.UNKNOWN_ERROR });\n }\n } else {\n debug('is error < 409 %o', err?.status);\n logger.error({ err: err }, 'unexpected error: @{!err.message}\\n@{err.stack}');\n if (!res.status || !res.send) {\n // TODO: decide which debug keep\n logger.error('this is an error in express.js, please report this');\n debug('this is an error in express.js, please report this, destroy response %o', err);\n res.destroy();\n } else if (!res.headersSent) {\n debug('report internal error %o', err);\n res.status(HTTP_STATUS.INTERNAL_ERROR);\n next({ error: API_ERROR.INTERNAL_SERVER_ERROR });\n } else {\n // socket should be already closed\n debug('this should not happen, otherwise report %o', err);\n }\n }\n };\n\n debug('error report middleware next()');\n next();\n };\n"],"mappings":"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"}
|
|
@@ -2,4 +2,4 @@ import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';
|
|
|
2
2
|
export declare const LOG_STATUS_MESSAGE = "@{status}, user: @{user}(@{remoteIP}), req: '@{request.method} @{request.url}'";
|
|
3
3
|
export declare const LOG_VERDACCIO_ERROR: string;
|
|
4
4
|
export declare const LOG_VERDACCIO_BYTES: string;
|
|
5
|
-
export declare
|
|
5
|
+
export declare const log: (logger: any) => (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) => void;
|
package/build/middlewares/log.js
CHANGED
|
@@ -3,10 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.LOG_VERDACCIO_ERROR = exports.LOG_VERDACCIO_BYTES = exports.LOG_STATUS_MESSAGE = void 0;
|
|
7
|
-
exports.log = log;
|
|
6
|
+
exports.log = exports.LOG_VERDACCIO_ERROR = exports.LOG_VERDACCIO_BYTES = exports.LOG_STATUS_MESSAGE = void 0;
|
|
8
7
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
9
|
-
var _logger = require("@verdaccio/logger");
|
|
10
8
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
9
|
// FIXME: deprecated, moved to @verdaccio/dev-commons
|
|
12
10
|
const LOG_STATUS_MESSAGE = "@{status}, user: @{user}(@{remoteIP}), req: '@{request.method} @{request.url}'";
|
|
@@ -15,87 +13,90 @@ const LOG_VERDACCIO_ERROR = `${LOG_STATUS_MESSAGE}, error: @{!error}`;
|
|
|
15
13
|
exports.LOG_VERDACCIO_ERROR = LOG_VERDACCIO_ERROR;
|
|
16
14
|
const LOG_VERDACCIO_BYTES = `${LOG_STATUS_MESSAGE}, bytes: @{bytes.in}/@{bytes.out}`;
|
|
17
15
|
exports.LOG_VERDACCIO_BYTES = LOG_VERDACCIO_BYTES;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
req.url = req.originalUrl;
|
|
32
|
-
req.log.info({
|
|
33
|
-
req: req,
|
|
34
|
-
ip: req.ip
|
|
35
|
-
}, "@{ip} requested '@{req.method} @{req.url}'");
|
|
36
|
-
req.originalUrl = req.url;
|
|
37
|
-
if (_lodash.default.isNil(_auth) === false) {
|
|
38
|
-
req.headers.authorization = _auth;
|
|
39
|
-
}
|
|
40
|
-
if (_lodash.default.isNil(_cookie) === false) {
|
|
41
|
-
req.headers.cookie = _cookie;
|
|
42
|
-
}
|
|
43
|
-
let bytesin = 0;
|
|
44
|
-
req.on('data', function (chunk) {
|
|
45
|
-
bytesin += chunk.length;
|
|
46
|
-
});
|
|
47
|
-
let bytesout = 0;
|
|
48
|
-
const _write = res.write;
|
|
49
|
-
// FIXME: res.write should return boolean
|
|
50
|
-
// @ts-ignore
|
|
51
|
-
res.write = function (buf) {
|
|
52
|
-
bytesout += buf.length;
|
|
53
|
-
/* eslint prefer-rest-params: "off" */
|
|
54
|
-
// @ts-ignore
|
|
55
|
-
_write.apply(res, arguments);
|
|
56
|
-
};
|
|
57
|
-
const log = function () {
|
|
58
|
-
var _req$remote_user;
|
|
59
|
-
const forwardedFor = req.get('x-forwarded-for');
|
|
60
|
-
const remoteAddress = req.connection.remoteAddress;
|
|
61
|
-
const remoteIP = forwardedFor ? `${forwardedFor} via ${remoteAddress}` : remoteAddress;
|
|
62
|
-
let message;
|
|
63
|
-
if (res.locals._verdaccio_error) {
|
|
64
|
-
message = LOG_VERDACCIO_ERROR;
|
|
65
|
-
} else {
|
|
66
|
-
message = LOG_VERDACCIO_BYTES;
|
|
16
|
+
const log = logger => {
|
|
17
|
+
return function log(req, res, next) {
|
|
18
|
+
// logger
|
|
19
|
+
req.log = logger.child({
|
|
20
|
+
sub: 'in'
|
|
21
|
+
});
|
|
22
|
+
const _auth = req.headers.authorization;
|
|
23
|
+
if (_lodash.default.isNil(_auth) === false) {
|
|
24
|
+
req.headers.authorization = '<Classified>';
|
|
25
|
+
}
|
|
26
|
+
const _cookie = req.get('cookie');
|
|
27
|
+
if (_lodash.default.isNil(_cookie) === false) {
|
|
28
|
+
req.headers.cookie = '<Classified>';
|
|
67
29
|
}
|
|
68
30
|
req.url = req.originalUrl;
|
|
69
|
-
req.log.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
},
|
|
74
|
-
user: ((_req$remote_user = req.remote_user) === null || _req$remote_user === void 0 ? void 0 : _req$remote_user.name) || null,
|
|
75
|
-
remoteIP,
|
|
76
|
-
status: res.statusCode,
|
|
77
|
-
error: res.locals._verdaccio_error,
|
|
78
|
-
bytes: {
|
|
79
|
-
in: bytesin,
|
|
80
|
-
out: bytesout
|
|
81
|
-
}
|
|
82
|
-
}, message);
|
|
31
|
+
req.log.info({
|
|
32
|
+
req: req,
|
|
33
|
+
ip: req.ip
|
|
34
|
+
}, "@{ip} requested '@{req.method} @{req.url}'");
|
|
83
35
|
req.originalUrl = req.url;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
log();
|
|
87
|
-
});
|
|
88
|
-
const _end = res.end;
|
|
89
|
-
// @ts-ignore
|
|
90
|
-
res.end = function (buf) {
|
|
91
|
-
if (buf) {
|
|
92
|
-
bytesout += buf.length;
|
|
36
|
+
if (_lodash.default.isNil(_auth) === false) {
|
|
37
|
+
req.headers.authorization = _auth;
|
|
93
38
|
}
|
|
94
|
-
|
|
39
|
+
if (_lodash.default.isNil(_cookie) === false) {
|
|
40
|
+
req.headers.cookie = _cookie;
|
|
41
|
+
}
|
|
42
|
+
let bytesin = 0;
|
|
43
|
+
req.on('data', function (chunk) {
|
|
44
|
+
bytesin += chunk.length;
|
|
45
|
+
});
|
|
46
|
+
let bytesout = 0;
|
|
47
|
+
const _write = res.write;
|
|
48
|
+
// FIXME: res.write should return boolean
|
|
49
|
+
// @ts-ignore
|
|
50
|
+
res.write = function (buf) {
|
|
51
|
+
bytesout += buf.length;
|
|
52
|
+
/* eslint prefer-rest-params: "off" */
|
|
53
|
+
// @ts-ignore
|
|
54
|
+
_write.apply(res, arguments);
|
|
55
|
+
};
|
|
56
|
+
const log = function () {
|
|
57
|
+
var _req$remote_user;
|
|
58
|
+
const forwardedFor = req.get('x-forwarded-for');
|
|
59
|
+
const remoteAddress = req.connection.remoteAddress;
|
|
60
|
+
const remoteIP = forwardedFor ? `${forwardedFor} via ${remoteAddress}` : remoteAddress;
|
|
61
|
+
let message;
|
|
62
|
+
if (res.locals._verdaccio_error) {
|
|
63
|
+
message = LOG_VERDACCIO_ERROR;
|
|
64
|
+
} else {
|
|
65
|
+
message = LOG_VERDACCIO_BYTES;
|
|
66
|
+
}
|
|
67
|
+
req.url = req.originalUrl;
|
|
68
|
+
req.log.http({
|
|
69
|
+
request: {
|
|
70
|
+
method: req.method,
|
|
71
|
+
url: req.url
|
|
72
|
+
},
|
|
73
|
+
user: ((_req$remote_user = req.remote_user) === null || _req$remote_user === void 0 ? void 0 : _req$remote_user.name) || null,
|
|
74
|
+
remoteIP,
|
|
75
|
+
status: res.statusCode,
|
|
76
|
+
error: res.locals._verdaccio_error,
|
|
77
|
+
bytes: {
|
|
78
|
+
in: bytesin,
|
|
79
|
+
out: bytesout
|
|
80
|
+
}
|
|
81
|
+
}, message);
|
|
82
|
+
req.originalUrl = req.url;
|
|
83
|
+
};
|
|
84
|
+
req.on('close', function () {
|
|
85
|
+
log();
|
|
86
|
+
});
|
|
87
|
+
const _end = res.end;
|
|
95
88
|
// @ts-ignore
|
|
96
|
-
|
|
97
|
-
|
|
89
|
+
res.end = function (buf) {
|
|
90
|
+
if (buf) {
|
|
91
|
+
bytesout += buf.length;
|
|
92
|
+
}
|
|
93
|
+
/* eslint prefer-rest-params: "off" */
|
|
94
|
+
// @ts-ignore
|
|
95
|
+
_end.apply(res, arguments);
|
|
96
|
+
log();
|
|
97
|
+
};
|
|
98
|
+
next();
|
|
98
99
|
};
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
};
|
|
101
|
+
exports.log = log;
|
|
101
102
|
//# sourceMappingURL=log.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.js","names":["LOG_STATUS_MESSAGE","LOG_VERDACCIO_ERROR","LOG_VERDACCIO_BYTES","log","req","res","next","
|
|
1
|
+
{"version":3,"file":"log.js","names":["LOG_STATUS_MESSAGE","LOG_VERDACCIO_ERROR","LOG_VERDACCIO_BYTES","log","logger","req","res","next","child","sub","_auth","headers","authorization","_","isNil","_cookie","get","cookie","url","originalUrl","info","ip","bytesin","on","chunk","length","bytesout","_write","write","buf","apply","arguments","forwardedFor","remoteAddress","connection","remoteIP","message","locals","_verdaccio_error","http","request","method","user","remote_user","name","status","statusCode","error","bytes","in","out","_end","end"],"sources":["../../src/middlewares/log.ts"],"sourcesContent":["import _ from 'lodash';\n\nimport { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';\n\n// FIXME: deprecated, moved to @verdaccio/dev-commons\nexport const LOG_STATUS_MESSAGE =\n \"@{status}, user: @{user}(@{remoteIP}), req: '@{request.method} @{request.url}'\";\nexport const LOG_VERDACCIO_ERROR = `${LOG_STATUS_MESSAGE}, error: @{!error}`;\nexport const LOG_VERDACCIO_BYTES = `${LOG_STATUS_MESSAGE}, bytes: @{bytes.in}/@{bytes.out}`;\n\nexport const log = (logger) => {\n return function log(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {\n // logger\n req.log = logger.child({ sub: 'in' });\n\n const _auth = req.headers.authorization;\n if (_.isNil(_auth) === false) {\n req.headers.authorization = '<Classified>';\n }\n\n const _cookie = req.get('cookie');\n if (_.isNil(_cookie) === false) {\n req.headers.cookie = '<Classified>';\n }\n\n req.url = req.originalUrl;\n req.log.info({ req: req, ip: req.ip }, \"@{ip} requested '@{req.method} @{req.url}'\");\n req.originalUrl = req.url;\n\n if (_.isNil(_auth) === false) {\n req.headers.authorization = _auth;\n }\n\n if (_.isNil(_cookie) === false) {\n req.headers.cookie = _cookie;\n }\n\n let bytesin = 0;\n req.on('data', function (chunk): void {\n bytesin += chunk.length;\n });\n\n let bytesout = 0;\n const _write = res.write;\n // FIXME: res.write should return boolean\n // @ts-ignore\n res.write = function (buf): boolean {\n bytesout += buf.length;\n /* eslint prefer-rest-params: \"off\" */\n // @ts-ignore\n _write.apply(res, arguments);\n };\n\n const log = function (): void {\n const forwardedFor = req.get('x-forwarded-for');\n const remoteAddress = req.connection.remoteAddress;\n const remoteIP = forwardedFor ? `${forwardedFor} via ${remoteAddress}` : remoteAddress;\n let message;\n if (res.locals._verdaccio_error) {\n message = LOG_VERDACCIO_ERROR;\n } else {\n message = LOG_VERDACCIO_BYTES;\n }\n\n req.url = req.originalUrl;\n req.log.http(\n {\n request: {\n method: req.method,\n url: req.url,\n },\n user: req.remote_user?.name || null,\n remoteIP,\n status: res.statusCode,\n error: res.locals._verdaccio_error,\n bytes: {\n in: bytesin,\n out: bytesout,\n },\n },\n message\n );\n req.originalUrl = req.url;\n };\n\n req.on('close', function (): void {\n log();\n });\n\n const _end = res.end;\n // @ts-ignore\n res.end = function (buf): void {\n if (buf) {\n bytesout += buf.length;\n }\n /* eslint prefer-rest-params: \"off\" */\n // @ts-ignore\n _end.apply(res, arguments);\n log();\n };\n next();\n };\n};\n"],"mappings":"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"}
|
package/jest.config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/middleware",
|
|
3
|
-
"version": "6.0.0-6-next.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "6.0.0-6-next.37",
|
|
4
|
+
"description": "express middleware utils",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
7
7
|
"author": {
|
|
@@ -26,13 +26,11 @@
|
|
|
26
26
|
"verdaccio"
|
|
27
27
|
],
|
|
28
28
|
"engines": {
|
|
29
|
-
"node": ">=
|
|
30
|
-
"npm": ">=6"
|
|
29
|
+
"node": ">=12"
|
|
31
30
|
},
|
|
32
31
|
"dependencies": {
|
|
33
|
-
"@verdaccio/core": "6.0.0-6-next.
|
|
34
|
-
"@verdaccio/
|
|
35
|
-
"@verdaccio/utils": "6.0.0-6-next.24",
|
|
32
|
+
"@verdaccio/core": "6.0.0-6-next.58",
|
|
33
|
+
"@verdaccio/utils": "6.0.0-6-next.26",
|
|
36
34
|
"debug": "4.3.4",
|
|
37
35
|
"lodash": "4.17.21",
|
|
38
36
|
"mime": "2.6.0"
|
|
@@ -42,6 +40,7 @@
|
|
|
42
40
|
"url": "https://opencollective.com/verdaccio"
|
|
43
41
|
},
|
|
44
42
|
"devDependencies": {
|
|
43
|
+
"@verdaccio/logger": "6.0.0-6-next.26",
|
|
45
44
|
"body-parser": "1.20.1",
|
|
46
45
|
"supertest": "6.3.3"
|
|
47
46
|
},
|
package/src/middlewares/allow.ts
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { API_ERROR, errorUtils } from '@verdaccio/core';
|
|
2
|
-
import { logger } from '@verdaccio/logger';
|
|
3
2
|
import { getVersionFromTarball } from '@verdaccio/utils';
|
|
4
3
|
|
|
5
4
|
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';
|
|
6
5
|
|
|
7
|
-
export function allow<T>(
|
|
6
|
+
export function allow<T>(
|
|
7
|
+
auth: T,
|
|
8
|
+
options = {
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
10
|
+
beforeAll: (_a: any, _b: any) => {},
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
12
|
+
afterAll: (_a: any, _b: any) => {},
|
|
13
|
+
}
|
|
14
|
+
): Function {
|
|
15
|
+
const { beforeAll, afterAll } = options;
|
|
8
16
|
return function (action: string): Function {
|
|
9
17
|
return function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
|
|
10
18
|
req.pause();
|
|
@@ -15,7 +23,7 @@ export function allow<T>(auth: T): Function {
|
|
|
15
23
|
? getVersionFromTarball(req.params.filename)
|
|
16
24
|
: undefined;
|
|
17
25
|
const remote = req.remote_user;
|
|
18
|
-
|
|
26
|
+
beforeAll?.(
|
|
19
27
|
{ action, user: remote?.name },
|
|
20
28
|
`[middleware/allow][@{action}] allow for @{user}`
|
|
21
29
|
);
|
|
@@ -27,6 +35,10 @@ export function allow<T>(auth: T): Function {
|
|
|
27
35
|
if (error) {
|
|
28
36
|
next(error);
|
|
29
37
|
} else if (allowed) {
|
|
38
|
+
afterAll?.(
|
|
39
|
+
{ action, user: remote?.name },
|
|
40
|
+
`[middleware/allow][@{action}] allowed for @{user}`
|
|
41
|
+
);
|
|
30
42
|
next();
|
|
31
43
|
} else {
|
|
32
44
|
// last plugin (that's our built-in one) returns either
|
package/src/middlewares/error.ts
CHANGED
|
@@ -3,76 +3,77 @@ import { HttpError } from 'http-errors';
|
|
|
3
3
|
import _ from 'lodash';
|
|
4
4
|
|
|
5
5
|
import { API_ERROR, HTTP_STATUS, VerdaccioError } from '@verdaccio/core';
|
|
6
|
-
import { logger } from '@verdaccio/logger';
|
|
7
6
|
|
|
8
7
|
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';
|
|
9
8
|
|
|
10
9
|
const debug = buildDebug('verdaccio:middleware:error');
|
|
11
10
|
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
11
|
+
export const handleError = (logger) =>
|
|
12
|
+
function handleError(
|
|
13
|
+
err: HttpError,
|
|
14
|
+
req: $RequestExtend,
|
|
15
|
+
res: $ResponseExtend,
|
|
16
|
+
next: $NextFunctionVer
|
|
17
|
+
) {
|
|
18
|
+
debug('error handler init');
|
|
19
|
+
if (_.isError(err)) {
|
|
20
|
+
debug('is native error');
|
|
21
|
+
if (err.code === 'ECONNABORT' && res.statusCode === HTTP_STATUS.NOT_MODIFIED) {
|
|
22
|
+
return next();
|
|
23
|
+
}
|
|
24
|
+
if (_.isFunction(res.locals.report_error) === false) {
|
|
25
|
+
debug('is locals error report ref');
|
|
26
|
+
// in case of very early error this middleware may not be loaded before error is generated
|
|
27
|
+
// fixing that
|
|
28
|
+
errorReportingMiddleware(logger)(req, res, _.noop);
|
|
29
|
+
}
|
|
30
|
+
debug('set locals error report ref');
|
|
31
|
+
res.locals.report_error(err);
|
|
32
|
+
} else {
|
|
33
|
+
// Fall to Middleware.final
|
|
34
|
+
debug('no error to report, jump next layer');
|
|
35
|
+
return next(err);
|
|
29
36
|
}
|
|
30
|
-
|
|
31
|
-
res.locals.report_error(err);
|
|
32
|
-
} else {
|
|
33
|
-
// Fall to Middleware.final
|
|
34
|
-
debug('no error to report, jump next layer');
|
|
35
|
-
return next(err);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
37
|
+
};
|
|
38
38
|
|
|
39
39
|
// Middleware
|
|
40
|
-
export
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
res.locals.report_error
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
debug('is error < 409 %o', err?.status);
|
|
59
|
-
logger.error({ err: err }, 'unexpected error: @{!err.message}\n@{err.stack}');
|
|
60
|
-
if (!res.status || !res.send) {
|
|
61
|
-
// TODO: decide which debug keep
|
|
62
|
-
logger.error('this is an error in express.js, please report this');
|
|
63
|
-
debug('this is an error in express.js, please report this, destroy response %o', err);
|
|
64
|
-
res.destroy();
|
|
65
|
-
} else if (!res.headersSent) {
|
|
66
|
-
debug('report internal error %o', err);
|
|
67
|
-
res.status(HTTP_STATUS.INTERNAL_ERROR);
|
|
68
|
-
next({ error: API_ERROR.INTERNAL_SERVER_ERROR });
|
|
40
|
+
export const errorReportingMiddleware = (logger) =>
|
|
41
|
+
function errorReportingMiddleware(
|
|
42
|
+
req: $RequestExtend,
|
|
43
|
+
res: $ResponseExtend,
|
|
44
|
+
next: $NextFunctionVer
|
|
45
|
+
): void {
|
|
46
|
+
debug('error report middleware');
|
|
47
|
+
res.locals.report_error =
|
|
48
|
+
res.locals.report_error ||
|
|
49
|
+
function (err: VerdaccioError): void {
|
|
50
|
+
if (err.status && err.status >= HTTP_STATUS.BAD_REQUEST && err.status < 600) {
|
|
51
|
+
debug('is error > 409 %o', err?.status);
|
|
52
|
+
if (_.isNil(res.headersSent) === false) {
|
|
53
|
+
debug('send status %o', err?.status);
|
|
54
|
+
res.status(err.status);
|
|
55
|
+
debug('next layer %o', err?.message);
|
|
56
|
+
next({ error: err.message || API_ERROR.UNKNOWN_ERROR });
|
|
57
|
+
}
|
|
69
58
|
} else {
|
|
70
|
-
|
|
71
|
-
|
|
59
|
+
debug('is error < 409 %o', err?.status);
|
|
60
|
+
logger.error({ err: err }, 'unexpected error: @{!err.message}\n@{err.stack}');
|
|
61
|
+
if (!res.status || !res.send) {
|
|
62
|
+
// TODO: decide which debug keep
|
|
63
|
+
logger.error('this is an error in express.js, please report this');
|
|
64
|
+
debug('this is an error in express.js, please report this, destroy response %o', err);
|
|
65
|
+
res.destroy();
|
|
66
|
+
} else if (!res.headersSent) {
|
|
67
|
+
debug('report internal error %o', err);
|
|
68
|
+
res.status(HTTP_STATUS.INTERNAL_ERROR);
|
|
69
|
+
next({ error: API_ERROR.INTERNAL_SERVER_ERROR });
|
|
70
|
+
} else {
|
|
71
|
+
// socket should be already closed
|
|
72
|
+
debug('this should not happen, otherwise report %o', err);
|
|
73
|
+
}
|
|
72
74
|
}
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
+
};
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
77
|
+
debug('error report middleware next()');
|
|
78
|
+
next();
|
|
79
|
+
};
|
package/src/middlewares/log.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
|
|
3
|
-
import { logger } from '@verdaccio/logger';
|
|
4
|
-
|
|
5
3
|
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';
|
|
6
4
|
|
|
7
5
|
// FIXME: deprecated, moved to @verdaccio/dev-commons
|
|
@@ -10,94 +8,96 @@ export const LOG_STATUS_MESSAGE =
|
|
|
10
8
|
export const LOG_VERDACCIO_ERROR = `${LOG_STATUS_MESSAGE}, error: @{!error}`;
|
|
11
9
|
export const LOG_VERDACCIO_BYTES = `${LOG_STATUS_MESSAGE}, bytes: @{bytes.in}/@{bytes.out}`;
|
|
12
10
|
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
export const log = (logger) => {
|
|
12
|
+
return function log(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
|
|
13
|
+
// logger
|
|
14
|
+
req.log = logger.child({ sub: 'in' });
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
const _auth = req.headers.authorization;
|
|
17
|
+
if (_.isNil(_auth) === false) {
|
|
18
|
+
req.headers.authorization = '<Classified>';
|
|
19
|
+
}
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
const _cookie = req.get('cookie');
|
|
22
|
+
if (_.isNil(_cookie) === false) {
|
|
23
|
+
req.headers.cookie = '<Classified>';
|
|
24
|
+
}
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
req.url = req.originalUrl;
|
|
27
|
+
req.log.info({ req: req, ip: req.ip }, "@{ip} requested '@{req.method} @{req.url}'");
|
|
28
|
+
req.originalUrl = req.url;
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
if (_.isNil(_auth) === false) {
|
|
31
|
+
req.headers.authorization = _auth;
|
|
32
|
+
}
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
if (_.isNil(_cookie) === false) {
|
|
35
|
+
req.headers.cookie = _cookie;
|
|
36
|
+
}
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
let bytesin = 0;
|
|
39
|
+
req.on('data', function (chunk): void {
|
|
40
|
+
bytesin += chunk.length;
|
|
41
|
+
});
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
// @ts-ignore
|
|
48
|
-
res.write = function (buf): boolean {
|
|
49
|
-
bytesout += buf.length;
|
|
50
|
-
/* eslint prefer-rest-params: "off" */
|
|
43
|
+
let bytesout = 0;
|
|
44
|
+
const _write = res.write;
|
|
45
|
+
// FIXME: res.write should return boolean
|
|
51
46
|
// @ts-ignore
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
res.write = function (buf): boolean {
|
|
48
|
+
bytesout += buf.length;
|
|
49
|
+
/* eslint prefer-rest-params: "off" */
|
|
50
|
+
// @ts-ignore
|
|
51
|
+
_write.apply(res, arguments);
|
|
52
|
+
};
|
|
54
53
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
54
|
+
const log = function (): void {
|
|
55
|
+
const forwardedFor = req.get('x-forwarded-for');
|
|
56
|
+
const remoteAddress = req.connection.remoteAddress;
|
|
57
|
+
const remoteIP = forwardedFor ? `${forwardedFor} via ${remoteAddress}` : remoteAddress;
|
|
58
|
+
let message;
|
|
59
|
+
if (res.locals._verdaccio_error) {
|
|
60
|
+
message = LOG_VERDACCIO_ERROR;
|
|
61
|
+
} else {
|
|
62
|
+
message = LOG_VERDACCIO_BYTES;
|
|
63
|
+
}
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
65
|
+
req.url = req.originalUrl;
|
|
66
|
+
req.log.http(
|
|
67
|
+
{
|
|
68
|
+
request: {
|
|
69
|
+
method: req.method,
|
|
70
|
+
url: req.url,
|
|
71
|
+
},
|
|
72
|
+
user: req.remote_user?.name || null,
|
|
73
|
+
remoteIP,
|
|
74
|
+
status: res.statusCode,
|
|
75
|
+
error: res.locals._verdaccio_error,
|
|
76
|
+
bytes: {
|
|
77
|
+
in: bytesin,
|
|
78
|
+
out: bytesout,
|
|
79
|
+
},
|
|
80
80
|
},
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
};
|
|
81
|
+
message
|
|
82
|
+
);
|
|
83
|
+
req.originalUrl = req.url;
|
|
84
|
+
};
|
|
86
85
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
req.on('close', function (): void {
|
|
87
|
+
log();
|
|
88
|
+
});
|
|
90
89
|
|
|
91
|
-
|
|
92
|
-
// @ts-ignore
|
|
93
|
-
res.end = function (buf): void {
|
|
94
|
-
if (buf) {
|
|
95
|
-
bytesout += buf.length;
|
|
96
|
-
}
|
|
97
|
-
/* eslint prefer-rest-params: "off" */
|
|
90
|
+
const _end = res.end;
|
|
98
91
|
// @ts-ignore
|
|
99
|
-
|
|
100
|
-
|
|
92
|
+
res.end = function (buf): void {
|
|
93
|
+
if (buf) {
|
|
94
|
+
bytesout += buf.length;
|
|
95
|
+
}
|
|
96
|
+
/* eslint prefer-rest-params: "off" */
|
|
97
|
+
// @ts-ignore
|
|
98
|
+
_end.apply(res, arguments);
|
|
99
|
+
log();
|
|
100
|
+
};
|
|
101
|
+
next();
|
|
101
102
|
};
|
|
102
|
-
|
|
103
|
-
}
|
|
103
|
+
};
|
package/test/allow.spec.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import request from 'supertest';
|
|
2
2
|
|
|
3
3
|
import { HTTP_STATUS } from '@verdaccio/core';
|
|
4
|
-
import { setup } from '@verdaccio/logger';
|
|
4
|
+
import { logger, setup } from '@verdaccio/logger';
|
|
5
5
|
|
|
6
6
|
import { allow } from '../src';
|
|
7
7
|
import { getApp } from './helper';
|
|
@@ -9,11 +9,14 @@ import { getApp } from './helper';
|
|
|
9
9
|
setup({});
|
|
10
10
|
|
|
11
11
|
test('should allow request', async () => {
|
|
12
|
-
const can = allow(
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
const can = allow(
|
|
13
|
+
{
|
|
14
|
+
allow_publish: (params, remove, cb) => {
|
|
15
|
+
return cb(null, true);
|
|
16
|
+
},
|
|
15
17
|
},
|
|
16
|
-
|
|
18
|
+
logger
|
|
19
|
+
);
|
|
17
20
|
const app = getApp([]);
|
|
18
21
|
// @ts-ignore
|
|
19
22
|
app.get('/:package', can('publish'), (req, res) => {
|
|
@@ -24,11 +27,14 @@ test('should allow request', async () => {
|
|
|
24
27
|
});
|
|
25
28
|
|
|
26
29
|
test('should allow scope request', async () => {
|
|
27
|
-
const can = allow(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
const can = allow(
|
|
31
|
+
{
|
|
32
|
+
allow_publish: (params, remove, cb) => {
|
|
33
|
+
return cb(null, true);
|
|
34
|
+
},
|
|
30
35
|
},
|
|
31
|
-
|
|
36
|
+
logger
|
|
37
|
+
);
|
|
32
38
|
const app = getApp([]);
|
|
33
39
|
// @ts-ignore
|
|
34
40
|
app.get('/:package/:scope', can('publish'), (req, res) => {
|
|
@@ -39,11 +45,14 @@ test('should allow scope request', async () => {
|
|
|
39
45
|
});
|
|
40
46
|
|
|
41
47
|
test('should allow filename request', async () => {
|
|
42
|
-
const can = allow(
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
const can = allow(
|
|
49
|
+
{
|
|
50
|
+
allow_publish: (params, remove, cb) => {
|
|
51
|
+
return cb(null, true);
|
|
52
|
+
},
|
|
45
53
|
},
|
|
46
|
-
|
|
54
|
+
logger
|
|
55
|
+
);
|
|
47
56
|
const app = getApp([]);
|
|
48
57
|
// @ts-ignore
|
|
49
58
|
app.get('/:filename', can('publish'), (req, res) => {
|
|
@@ -54,11 +63,14 @@ test('should allow filename request', async () => {
|
|
|
54
63
|
});
|
|
55
64
|
|
|
56
65
|
test('should not allow request', async () => {
|
|
57
|
-
const can = allow(
|
|
58
|
-
|
|
59
|
-
|
|
66
|
+
const can = allow(
|
|
67
|
+
{
|
|
68
|
+
allow_publish: (params, remove, cb) => {
|
|
69
|
+
return cb(null, false);
|
|
70
|
+
},
|
|
60
71
|
},
|
|
61
|
-
|
|
72
|
+
logger
|
|
73
|
+
);
|
|
62
74
|
const app = getApp([]);
|
|
63
75
|
// @ts-ignore
|
|
64
76
|
app.get('/sec', can('publish'), (req, res) => {
|
|
@@ -69,11 +81,14 @@ test('should not allow request', async () => {
|
|
|
69
81
|
});
|
|
70
82
|
|
|
71
83
|
test('should handle error request', async () => {
|
|
72
|
-
const can = allow(
|
|
73
|
-
|
|
74
|
-
|
|
84
|
+
const can = allow(
|
|
85
|
+
{
|
|
86
|
+
allow_publish: (params, remove, cb) => {
|
|
87
|
+
return cb(Error('foo error'));
|
|
88
|
+
},
|
|
75
89
|
},
|
|
76
|
-
|
|
90
|
+
logger
|
|
91
|
+
);
|
|
77
92
|
const app = getApp([]);
|
|
78
93
|
// @ts-ignore
|
|
79
94
|
app.get('/err', can('publish'));
|
package/test/log.spec.ts
CHANGED
|
@@ -2,7 +2,7 @@ import path from 'path';
|
|
|
2
2
|
import request from 'supertest';
|
|
3
3
|
|
|
4
4
|
import { HTTP_STATUS } from '@verdaccio/core';
|
|
5
|
-
import { setup } from '@verdaccio/logger';
|
|
5
|
+
import { logger, setup } from '@verdaccio/logger';
|
|
6
6
|
|
|
7
7
|
import { log } from '../src';
|
|
8
8
|
import { getApp } from './helper';
|
|
@@ -17,7 +17,7 @@ setup({
|
|
|
17
17
|
test('should log request', async () => {
|
|
18
18
|
const app = getApp([]);
|
|
19
19
|
// @ts-ignore
|
|
20
|
-
app.use(log);
|
|
20
|
+
app.use(log(logger));
|
|
21
21
|
// @ts-ignore
|
|
22
22
|
app.get('/:package', (req, res) => {
|
|
23
23
|
res.status(HTTP_STATUS.OK).json({});
|