zsyp 1.0.1 → 1.1.0
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/Readme.md +2 -2
- package/index.js +4 -13
- package/lib/app.js +21 -0
- package/lib/filter.js +4 -5
- package/lib/from.js +3 -2
- package/lib/logger.js +11 -4
- package/lib/router.js +44 -0
- package/package.json +2 -1
- package/lib/csp.js +0 -36
package/Readme.md
CHANGED
|
@@ -74,8 +74,8 @@ MIT © [Damian Krzeminski](https://pirxpilot.me)
|
|
|
74
74
|
[npm-image]: https://img.shields.io/npm/v/zsyp
|
|
75
75
|
[npm-url]: https://npmjs.org/package/zsyp
|
|
76
76
|
|
|
77
|
-
[build-url]: https://
|
|
78
|
-
[build-image]: https://img.shields.io/
|
|
77
|
+
[build-url]: https://github.com/pirxpilot/zsyp/actions/workflows/check.yaml
|
|
78
|
+
[build-image]: https://img.shields.io/github/workflow/status/pirxpilot/zsyp/check
|
|
79
79
|
|
|
80
80
|
[deps-image]: https://img.shields.io/librariesio/release/npm/zsyp
|
|
81
81
|
[deps-url]: https://libraries.io/npm/zsyp
|
package/index.js
CHANGED
|
@@ -1,24 +1,15 @@
|
|
|
1
1
|
require('dotenv').config({ path: '/etc/default/zsyp' });
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const makeLogger = require('./lib/logger');
|
|
3
|
+
const logger = require('./lib/logger');
|
|
4
|
+
const makeApp = require('./lib/app');
|
|
6
5
|
|
|
7
6
|
const {
|
|
8
7
|
ZSYP_PORT: PORT = 3090,
|
|
9
|
-
ZSYP_DOMAINS: domains,
|
|
10
|
-
ZSYP_DB: database = 'mongodb://localhost/zsyp'
|
|
11
8
|
} = process.env;
|
|
12
9
|
|
|
13
|
-
const app =
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
app.use(function (req, res, next) {
|
|
17
|
-
req.log = log;
|
|
18
|
-
next();
|
|
10
|
+
const app = makeApp({
|
|
11
|
+
logger
|
|
19
12
|
});
|
|
20
|
-
app.use(router({ domains }));
|
|
21
|
-
|
|
22
13
|
|
|
23
14
|
module.exports = app;
|
|
24
15
|
|
package/lib/app.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const connect = require('@pirxpilot/connect');
|
|
2
|
+
const { json } = require('body-parser');
|
|
3
|
+
const router = require('./router');
|
|
4
|
+
|
|
5
|
+
module.exports = makeApp;
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
ZSYP_DOMAINS: domains,
|
|
9
|
+
} = process.env;
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
function makeApp(opts) {
|
|
13
|
+
const app = connect();
|
|
14
|
+
|
|
15
|
+
app.use(json({ limit: 5000, type: ['*/json', 'application/csp-report'] }));
|
|
16
|
+
app.use('/csp', router({ ...opts, name: 'csp', domains }));
|
|
17
|
+
app.use('/event', router({ ...opts, name: 'event' }));
|
|
18
|
+
|
|
19
|
+
return app;
|
|
20
|
+
}
|
|
21
|
+
|
package/lib/filter.js
CHANGED
|
@@ -4,18 +4,17 @@ module.exports = makeFilter;
|
|
|
4
4
|
|
|
5
5
|
function makeFilter({ domains }) {
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
if (!domains) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
8
10
|
|
|
11
|
+
const domainRe = domains && new RegExp(domains);
|
|
9
12
|
return filter;
|
|
10
13
|
|
|
11
14
|
function filter({ body: csp }, res, next) {
|
|
12
|
-
if (!domainRe) {
|
|
13
|
-
return next();
|
|
14
|
-
}
|
|
15
15
|
const uri = csp['csp-report']['document-uri'];
|
|
16
16
|
const { hostname } = new URL(uri);
|
|
17
17
|
if (domainRe.test(hostname)) {
|
|
18
|
-
console.log('OK!!!!!!!!');
|
|
19
18
|
return next();
|
|
20
19
|
}
|
|
21
20
|
}
|
package/lib/from.js
CHANGED
|
@@ -3,7 +3,8 @@ const { parse } = require('useragent');
|
|
|
3
3
|
module.exports = from;
|
|
4
4
|
|
|
5
5
|
function from(req, res, next) {
|
|
6
|
-
const
|
|
6
|
+
const { headers, body } = req;
|
|
7
|
+
const ua = body?.from?.ua ?? headers['user-agent'];
|
|
7
8
|
const {
|
|
8
9
|
family,
|
|
9
10
|
major,
|
|
@@ -20,7 +21,7 @@ function from(req, res, next) {
|
|
|
20
21
|
name: os.family,
|
|
21
22
|
version: os.major
|
|
22
23
|
},
|
|
23
|
-
ip:
|
|
24
|
+
ip: body?.from?.ip ?? headers['x-forwarded-for'] ?? req.connection.remoteAddress
|
|
24
25
|
};
|
|
25
26
|
if (device.family !== 'Other') {
|
|
26
27
|
data.device = device.family;
|
package/lib/logger.js
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
const
|
|
1
|
+
const mniam = require('mniam');
|
|
2
2
|
const debug = require('debug')('zsyp:logger');
|
|
3
3
|
|
|
4
4
|
module.exports = makeLogger;
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
const {
|
|
7
|
+
ZSYP_DB: database = 'mongodb://localhost/zsyp'
|
|
8
|
+
} = process.env;
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const db = mniam.db(database);
|
|
12
|
+
|
|
13
|
+
function makeLogger({ name }) {
|
|
14
|
+
const collection = db.collection({ name });
|
|
8
15
|
|
|
9
16
|
return log;
|
|
10
17
|
|
|
11
18
|
function log(report) {
|
|
12
19
|
debug('saving %j', report);
|
|
13
|
-
|
|
20
|
+
collection.insertOne(report, function(err) {
|
|
14
21
|
if (err) {
|
|
15
22
|
console.error(err);
|
|
16
23
|
}
|
package/lib/router.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const Router = require('router');
|
|
2
|
+
const debug = require('debug')('zsyp:router');
|
|
3
|
+
|
|
4
|
+
const from = require('./from');
|
|
5
|
+
const makeFilter = require('./filter');
|
|
6
|
+
|
|
7
|
+
function respond(req, res, next) {
|
|
8
|
+
res.statusCode = 204; // empty
|
|
9
|
+
res.end();
|
|
10
|
+
next();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = function (opts) {
|
|
14
|
+
const router = new Router({
|
|
15
|
+
strict: true,
|
|
16
|
+
caseSensitive: true
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const stack = [
|
|
20
|
+
from,
|
|
21
|
+
respond
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const filter = makeFilter(opts);
|
|
25
|
+
if (filter) {
|
|
26
|
+
stack.push(filter);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const logger = opts.logger(opts);
|
|
30
|
+
|
|
31
|
+
router.post('/', ...stack, log);
|
|
32
|
+
|
|
33
|
+
return router;
|
|
34
|
+
|
|
35
|
+
function log({ from, body }) {
|
|
36
|
+
const report = {
|
|
37
|
+
...body,
|
|
38
|
+
from
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
debug('Logging report %j', report);
|
|
42
|
+
logger(report);
|
|
43
|
+
}
|
|
44
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zsyp",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "CSP violation reports logger.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Damian Krzeminski",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"dotenv": "~16",
|
|
23
23
|
"mniam": "^2.1.0",
|
|
24
24
|
"router": "~1",
|
|
25
|
+
"supertest": "~6",
|
|
25
26
|
"useragent": "^2.3.0"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
package/lib/csp.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
const Router = require('router');
|
|
2
|
-
const { json } = require('body-parser');
|
|
3
|
-
|
|
4
|
-
const from = require('./from');
|
|
5
|
-
const makeFilter = require('./filter');
|
|
6
|
-
|
|
7
|
-
function respond(req, res, next) {
|
|
8
|
-
res.statusCode = 204; // empty
|
|
9
|
-
res.end();
|
|
10
|
-
next();
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
function log({ from, body: csp, log }) {
|
|
15
|
-
const report = {
|
|
16
|
-
from,
|
|
17
|
-
...csp
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
log(report);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
module.exports = function (opts) {
|
|
24
|
-
const router = new Router();
|
|
25
|
-
const filter = makeFilter(opts);
|
|
26
|
-
|
|
27
|
-
router.post('/csp',
|
|
28
|
-
from,
|
|
29
|
-
json({ limit: 5000, type: [ '*/json', 'application/csp-report' ] }),
|
|
30
|
-
respond,
|
|
31
|
-
filter,
|
|
32
|
-
log
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
return router;
|
|
36
|
-
};
|