koa-helmet 3.3.0 → 4.2.1

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/.eslintrc.js ADDED
@@ -0,0 +1,39 @@
1
+ module.exports = {
2
+ "env": {
3
+ "es6": true,
4
+ "node": true
5
+ },
6
+ "extends": [
7
+ "eslint:recommended",
8
+ "plugin:node/recommended"
9
+ ],
10
+ "parserOptions": {
11
+ "ecmaVersion": 2017,
12
+ "sourceType": "module"
13
+ },
14
+ "plugins": [
15
+ "node"
16
+ ],
17
+ "rules": {
18
+ "indent": [
19
+ "error",
20
+ 2
21
+ ],
22
+ "linebreak-style": [
23
+ "error",
24
+ "unix"
25
+ ],
26
+ "quotes": [
27
+ "error",
28
+ "single"
29
+ ],
30
+ "semi": [
31
+ "error",
32
+ "always"
33
+ ],
34
+ "space-before-function-paren": [
35
+ "error",
36
+ "always"
37
+ ]
38
+ }
39
+ };
package/.travis.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  language: node_js
2
2
  node_js:
3
- - "9"
3
+ - "12"
4
+ - "10"
4
5
  - "8"
5
- - "7"
6
6
  - "6"
7
7
  after_success: yarn run coverage
package/README.md CHANGED
@@ -5,7 +5,7 @@ koa-helmet
5
5
  [![Build Status](https://img.shields.io/travis/venables/koa-helmet/master.svg)](https://travis-ci.org/venables/koa-helmet)
6
6
  [![Coverage Status](https://img.shields.io/coveralls/venables/koa-helmet.svg)](https://coveralls.io/github/venables/koa-helmet)
7
7
  [![Dependency Status](https://img.shields.io/david/venables/koa-helmet.svg)](https://david-dm.org/venables/koa-helmet)
8
- [![Standard - JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
8
+ [![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg?style=flat-square)](https://github.com/Flet/semistandard)
9
9
  [![Downloads](https://img.shields.io/npm/dm/koa-helmet.svg)](https://www.npmjs.com/package/koa-helmet)
10
10
 
11
11
  koa-helmet is a wrapper for [helmet](https://github.com/helmetjs/helmet) to work with [koa](https://github.com/koajs/koa). It provides important security headers to make your app more secure by default.
@@ -28,12 +28,15 @@ Usage
28
28
 
29
29
  Usage is the same as [helmet](https://github.com/helmetjs/helmet)
30
30
 
31
- Helmet offers 11 security middleware functions:
31
+ Helmet offers 14 security middleware functions:
32
32
 
33
33
  | Module | Default? |
34
34
  |---|---|
35
35
  | [contentSecurityPolicy](https://helmetjs.github.io/docs/csp/) for setting Content Security Policy | |
36
+ | [permittedCrossDomainPolicies](https://helmetjs.github.io/docs/crossdomain/) for handling Adobe products' crossdomain requests | |
36
37
  | [dnsPrefetchControl](https://helmetjs.github.io/docs/dns-prefetch-control) controls browser DNS prefetching | ✓ |
38
+ | [expectCt](https://helmetjs.github.io/docs/expect-ct/) for handling Certificate Transparency | |
39
+ | [featurePolicy](https://helmetjs.github.io/docs/feature-policy/) to limit your site's features | |
37
40
  | [frameguard](https://helmetjs.github.io/docs/frameguard/) to prevent clickjacking | ✓ |
38
41
  | [hidePoweredBy](https://helmetjs.github.io/docs/hide-powered-by) to remove the X-Powered-By header | ✓ |
39
42
  | [hpkp](https://helmetjs.github.io/docs/hpkp/) for HTTP Public Key Pinning | |
@@ -57,17 +60,19 @@ Example
57
60
  -------
58
61
 
59
62
  ```js
60
- const Koa = require('koa')
61
- const helmet = require('koa-helmet')
62
- const app = new Koa()
63
+ "use strict";
63
64
 
64
- app.use(helmet())
65
+ const Koa = require("koa");
66
+ const helmet = require("koa-helmet");
67
+ const app = new Koa();
68
+
69
+ app.use(helmet());
65
70
 
66
71
  app.use((ctx) => {
67
- ctx.body = 'Hello World'
68
- })
72
+ ctx.body = "Hello World"
73
+ });
69
74
 
70
- app.listen(4000)
75
+ app.listen(4000);
71
76
  ```
72
77
 
73
78
 
package/lib/koa-helmet.js CHANGED
@@ -1,29 +1,29 @@
1
- 'use strict'
1
+ 'use strict';
2
2
 
3
- const helmet = require('helmet')
4
- const promisify = require('./promisify')
3
+ const helmet = require('helmet');
4
+ const promisify = require('./promisify');
5
5
 
6
6
  const koaHelmet = function () {
7
- const helmetPromise = promisify(helmet.apply(null, arguments))
7
+ const helmetPromise = promisify(helmet.apply(null, arguments));
8
8
 
9
9
  const middleware = (ctx, next) => {
10
- ctx.req.secure = ctx.request.secure
11
- return helmetPromise(ctx.req, ctx.res).then(next)
12
- }
13
- middleware._name = 'helmet'
14
- return middleware
15
- }
10
+ ctx.req.secure = ctx.request.secure;
11
+ return helmetPromise(ctx.req, ctx.res).then(next);
12
+ };
13
+ middleware._name = 'helmet';
14
+ return middleware;
15
+ };
16
16
 
17
17
  Object.keys(helmet).forEach(function (helmetMethod) {
18
18
  koaHelmet[helmetMethod] = function () {
19
- const method = helmet[helmetMethod]
20
- const methodPromise = promisify(method.apply(null, arguments))
19
+ const method = helmet[helmetMethod];
20
+ const methodPromise = promisify(method.apply(null, arguments));
21
21
 
22
22
  return (ctx, next) => {
23
- ctx.req.secure = ctx.request.secure
24
- return methodPromise(ctx.req, ctx.res).then(next)
25
- }
26
- }
27
- })
23
+ ctx.req.secure = ctx.request.secure;
24
+ return methodPromise(ctx.req, ctx.res).then(next);
25
+ };
26
+ };
27
+ });
28
28
 
29
- module.exports = koaHelmet
29
+ module.exports = koaHelmet;
package/lib/promisify.js CHANGED
@@ -1,4 +1,4 @@
1
- 'use strict'
1
+ 'use strict';
2
2
 
3
3
  /**
4
4
  * Takes an express-style middleware and returns a promise-based version (returning a Promise,
@@ -7,18 +7,18 @@
7
7
  * @param {Function} middleware - The middleware to promisify
8
8
  * @returns {Function} - The middleware function updated to return a Promise, not call a callback
9
9
  */
10
- const promisify = function koaHelmetPromisify (middleware) {
10
+ function koaHelmetPromisify (middleware) {
11
11
  return function (req, res) {
12
12
  return new Promise(function (resolve, reject) {
13
13
  middleware(req, res, function (err) {
14
14
  if (err) {
15
- return reject(err)
15
+ return reject(err);
16
16
  }
17
17
 
18
- return resolve()
19
- })
20
- })
21
- }
18
+ return resolve();
19
+ });
20
+ });
21
+ };
22
22
  }
23
23
 
24
- module.exports = promisify
24
+ module.exports = koaHelmetPromisify;
package/package.json CHANGED
@@ -3,10 +3,12 @@
3
3
  "author": "Matt Venables <mattvenables@gmail.com>",
4
4
  "description": "Security header middleware collection for koa",
5
5
  "license": "MIT",
6
- "version": "3.3.0",
6
+ "version": "4.2.1",
7
7
  "main": "lib/koa-helmet.js",
8
8
  "scripts": {
9
- "test": "standard && NODE_ENV=test nyc --reporter=lcov --reporter=text mocha 'test/**/*.spec.js' --exit",
9
+ "format": "eslint lib test --fix",
10
+ "lint": "eslint lib test",
11
+ "test": "eslint lib test && nyc ava",
10
12
  "coverage": "nyc report --reporter=text-lcov | coveralls"
11
13
  },
12
14
  "keywords": [
@@ -21,17 +23,24 @@
21
23
  "url": "git://github.com/venables/koa-helmet.git"
22
24
  },
23
25
  "engines": {
24
- "node": ">= 4.0.0"
26
+ "node": ">= 6.0.0"
25
27
  },
26
28
  "dependencies": {
27
- "helmet": "^3.9.0"
29
+ "helmet": "^3.15.1"
28
30
  },
29
31
  "devDependencies": {
30
- "coveralls": "^3.0.0",
31
- "koa": "^2.4.1",
32
- "mocha": "^4.0.1",
33
- "nyc": "^11.3.0",
34
- "standard": "^10.0.3",
35
- "supertest": "^3.0.0"
32
+ "ava": "^1.3.1",
33
+ "coveralls": "^3.0.3",
34
+ "eslint": "^5.15.1",
35
+ "eslint-plugin-node": "^8.0.1",
36
+ "koa": "^2.7.0",
37
+ "nyc": "^13.3.0",
38
+ "supertest": "^4.0.0"
39
+ },
40
+ "nyc": {
41
+ "reporter": [
42
+ "lcov",
43
+ "text"
44
+ ]
36
45
  }
37
46
  }
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ "rules": {
3
+ "node/no-unpublished-require": "off"
4
+ }
5
+ };
@@ -1,84 +1,118 @@
1
- 'use strict'
2
-
3
- /* eslint-env mocha */
4
-
5
- const helmet = require('../')
6
- const Koa = require('koa')
7
- const request = require('supertest')
8
-
9
- describe('integration', function () {
10
- let app
11
-
12
- beforeEach(function () {
13
- app = new Koa()
14
- })
15
-
16
- describe('default options', function () {
17
- it('works with the default helmet call', function () {
18
- app.use(helmet())
19
- app.use((ctx, next) => {
20
- ctx.body = 'Hello world!'
21
- })
22
-
23
- return request(app.listen())
24
- .get('/')
25
- // dnsPrefetchControl
26
- .expect('X-DNS-Prefetch-Control', 'off')
27
- // frameguard
28
- .expect('X-Frame-Options', 'SAMEORIGIN')
29
- // hsts: Not enabled in HTTP
30
- // .expect('Strict-Transport-Security', 'max-age=5184000; includeSubDomains')
31
- // ieNoOpen
32
- .expect('X-Download-Options', 'noopen')
33
- // noSniff
34
- .expect('X-Content-Type-Options', 'nosniff')
35
- // xssFilter
36
- .expect('X-XSS-Protection', '1; mode=block')
37
- .expect(200)
1
+ 'use strict';
2
+
3
+ const helmet = require('../');
4
+ const Koa = require('koa');
5
+ const request = require('supertest');
6
+ const test = require('ava');
7
+
8
+ test('it works with the default helmet call', t => {
9
+ const app = new Koa();
10
+ app.use(helmet());
11
+ app.use((ctx) => {
12
+ ctx.body = 'Hello world!';
13
+ });
14
+
15
+ return (
16
+ request(app.listen())
17
+ .get('/')
18
+
19
+ // dnsPrefetchControl
20
+ .expect('X-DNS-Prefetch-Control', 'off')
21
+
22
+ // frameguard
23
+ .expect('X-Frame-Options', 'SAMEORIGIN')
24
+
25
+ // hsts: Not enabled in HTTP
26
+ .expect('Strict-Transport-Security', 'max-age=15552000; includeSubDomains')
27
+
28
+ // ieNoOpen
29
+ .expect('X-Download-Options', 'noopen')
30
+
31
+ // noSniff
32
+ .expect('X-Content-Type-Options', 'nosniff')
33
+
34
+ // xssFilter
35
+ .expect('X-XSS-Protection', '1; mode=block')
36
+ .expect(200)
37
+ .then(() => t.pass())
38
+ .catch(err => t.fail(err))
39
+ );
40
+ });
41
+
42
+ test('it sets individual headers properly', t => {
43
+ const app = new Koa();
44
+ app.use(
45
+ helmet.hsts({
46
+ force: true
38
47
  })
39
- })
40
-
41
- describe('individual calls', function () {
42
- it('sets the headers properly', function () {
43
- app.use(helmet.hsts({
44
- force: true
45
- }))
46
- app.use(helmet.noCache())
47
- app.use(helmet.xssFilter())
48
- app.use(helmet.frameguard('deny'))
49
- app.use(helmet.noSniff())
50
- app.use(helmet.hpkp({
51
- maxAge: 1000,
52
- sha256s: ['AbCdEf123=', 'ZyXwVu456='],
53
- includeSubdomains: true,
54
- reportUri: 'http://example.com'
55
- }))
56
-
57
- app.use((ctx) => {
58
- ctx.body = 'Hello world!'
59
- })
60
-
61
- return request(app.listen())
62
- .get('/')
63
- // noCache
64
- .expect('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate')
65
- .expect('Pragma', 'no-cache')
66
- .expect('Expires', '0')
67
-
68
- // hsts
69
- .expect('Strict-Transport-Security', 'max-age=15552000; includeSubDomains')
70
-
71
- // xssFilter
72
- .expect('X-XSS-Protection', '1; mode=block')
73
-
74
- // frameguard
75
- .expect('X-Frame-Options', 'SAMEORIGIN')
76
-
77
- // noSniff
78
- .expect('X-Content-Type-Options', 'nosniff')
79
-
80
- // hpkp
81
- .expect('Public-Key-Pins', 'pin-sha256="AbCdEf123="; pin-sha256="ZyXwVu456="; max-age=1000; includeSubDomains; report-uri="http://example.com"')
48
+ );
49
+ app.use(helmet.noCache());
50
+ app.use(helmet.xssFilter());
51
+ app.use(helmet.frameguard('deny'));
52
+ app.use(helmet.noSniff());
53
+ app.use(helmet.permittedCrossDomainPolicies());
54
+ app.use(helmet.expectCt());
55
+ app.use(helmet.featurePolicy({
56
+ features: {
57
+ fullscreen: ['\'self\''],
58
+ notifications: ['\'none\''],
59
+ vibrate: ['\'none\'']
60
+ }
61
+ }));
62
+ app.use(
63
+ helmet.hpkp({
64
+ maxAge: 1000,
65
+ sha256s: ['AbCdEf123=', 'ZyXwVu456='],
66
+ includeSubdomains: true,
67
+ reportUri: 'http://example.com'
82
68
  })
83
- })
84
- })
69
+ );
70
+
71
+ app.use(ctx => {
72
+ ctx.body = 'Hello world!';
73
+ });
74
+
75
+ return (
76
+ request(app.listen())
77
+ .get('/')
78
+ // noCache
79
+ .expect(
80
+ 'Cache-Control',
81
+ 'no-store, no-cache, must-revalidate, proxy-revalidate'
82
+ )
83
+ .expect('Pragma', 'no-cache')
84
+ .expect('Expires', '0')
85
+
86
+ // hsts
87
+ .expect(
88
+ 'Strict-Transport-Security',
89
+ 'max-age=15552000; includeSubDomains'
90
+ )
91
+
92
+ // xssFilter
93
+ .expect('X-XSS-Protection', '1; mode=block')
94
+
95
+ // frameguard
96
+ .expect('X-Frame-Options', 'SAMEORIGIN')
97
+
98
+ // noSniff
99
+ .expect('X-Content-Type-Options', 'nosniff')
100
+
101
+ // permittedCrossDomainPolicies
102
+ .expect('X-Permitted-Cross-Domain-Policies', 'none')
103
+
104
+ // expectCt
105
+ .expect('Expect-CT', 'max-age=0')
106
+
107
+ // featurePolicy
108
+ .expect('Feature-Policy', 'fullscreen \'self\';notifications \'none\';vibrate \'none\'')
109
+
110
+ // hpkp
111
+ .expect(
112
+ 'Public-Key-Pins',
113
+ 'pin-sha256="AbCdEf123="; pin-sha256="ZyXwVu456="; max-age=1000; includeSubDomains; report-uri="http://example.com"'
114
+ )
115
+ .then(() => t.pass())
116
+ .catch(err => t.fail(err))
117
+ );
118
+ });
@@ -1,33 +1,38 @@
1
- 'use strict'
1
+ 'use strict';
2
2
 
3
- /* eslint-env mocha */
4
-
5
- const promisify = require('../lib/promisify')
3
+ const promisify = require('../lib/promisify');
4
+ const test = require('ava');
6
5
 
7
6
  function passingMiddleware (req, res, next) {
8
- return next()
7
+ return next();
9
8
  }
10
9
 
11
10
  function failingMiddleware (req, res, next) {
12
- return next(new Error('Expected Failure'))
11
+ return next(new Error('Expected Failure'));
13
12
  }
14
13
 
15
- describe('promisify', function () {
16
- it('returns a promisified version of the middleware which resolves the Promise on success', function () {
17
- let middleware = promisify(passingMiddleware)
18
-
19
- return middleware().catch((err) => {
20
- throw err
21
- })
22
- })
23
-
24
- it('returns a promisified version of the middleware which rejects the Promise on failure', function () {
25
- let middleware = promisify(failingMiddleware)
26
-
27
- return middleware().then(() => {
28
- throw new Error('Unexpected Success!')
29
- }, () => {
30
- // Expect failure, do not fail test
31
- })
32
- })
33
- })
14
+ test('returns a promisified version of the middleware which resolves the Promise on success', t => {
15
+ let middleware = promisify(passingMiddleware);
16
+
17
+ return middleware().then(
18
+ () => {
19
+ t.pass();
20
+ },
21
+ err => {
22
+ t.fail(err);
23
+ }
24
+ );
25
+ });
26
+
27
+ test('returns a promisified version of the middleware which rejects the Promise on failure', t => {
28
+ let middleware = promisify(failingMiddleware);
29
+
30
+ return middleware().then(
31
+ () => {
32
+ t.fail('Unexpected Success!');
33
+ },
34
+ () => {
35
+ t.pass();
36
+ }
37
+ );
38
+ });