Use standard style guide 🎉

This commit is contained in:
retrohacker 2017-05-22 09:03:45 -07:00 committed by Romain
parent b55478854d
commit 3d0f3257a6
10 changed files with 252 additions and 261 deletions

View file

@ -11,6 +11,8 @@
[![Peer dependencies](http://img.shields.io/david/peer/TabDigital/restify-cors-middleware.svg?style=flat)](https://david-dm.org/TabDigital/restify-cors-middleware)
[![Known Vulnerabilities](https://snyk.io/package/npm/restify-cors-middleware/badge.svg)](https://snyk.io/package/npm/restify-cors-middleware)
[![JavaScript Style Guide](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard)
## Usage
```js

View file

@ -16,16 +16,16 @@
},
"main": "src/index.js",
"scripts": {
"test": "./node_modules/.bin/mocha"
"test": "standard && ./node_modules/.bin/mocha"
},
"peerDependencies": {
"restify": "2.6.x - 4.3.x"
},
"devDependencies": {
"mocha": "~3.4.1",
"should": "~11.2.1",
"restify": "~4.3.0",
"should": "~11.2.1",
"standard": "^10.0.2",
"supertest": "~3.0.0"
},
"dependencies": {

View file

@ -1,27 +1,25 @@
var origin = require('./origin.js');
var constants = require('./constants.js');
var origin = require('./origin.js')
var constants = require('./constants.js')
exports.handler = function(options) {
return function(req, res, next) {
var originHeader = req.headers['origin'];
exports.handler = function (options) {
return function (req, res, next) {
var originHeader = req.headers['origin']
// If either no origin was set, or the origin isn't supported, continue
// without setting any headers
if (!originHeader || !origin.match(originHeader, options.origins)) {
return next();
return next()
}
// if match was found, let's set some headers.
res.setHeader(constants['AC_ALLOW_ORIGIN'], originHeader);
res.setHeader(constants['STR_VARY'], constants['STR_ORIGIN']);
if(options.credentials) {
res.setHeader(constants['AC_ALLOW_CREDS'], 'true');
res.setHeader(constants['AC_ALLOW_ORIGIN'], originHeader)
res.setHeader(constants['STR_VARY'], constants['STR_ORIGIN'])
if (options.credentials) {
res.setHeader(constants['AC_ALLOW_CREDS'], 'true')
}
res.setHeader(constants['AC_EXPOSE_HEADERS'],
options.exposeHeaders.join(', '));
options.exposeHeaders.join(', '))
return next();
};
};
return next()
}
}

View file

@ -1,7 +1,7 @@
var assert = require('assert-plus');
var preflight = require('./preflight');
var actual = require('./actual');
var constants = require('./constants.js');
var assert = require('assert-plus')
var preflight = require('./preflight')
var actual = require('./actual')
var constants = require('./constants.js')
/**
* From http://www.w3.org/TR/cors/#resource-processing-model
@ -33,47 +33,45 @@ var constants = require('./constants.js');
* customize preflight request handling
* @returns {Object} returns an object with actual and preflight handlers
*/
module.exports = function(options) {
assert.object(options, 'options');
assert.optionalArray(options.origins, 'options.origins');
module.exports = function (options) {
assert.object(options, 'options')
assert.optionalArray(options.origins, 'options.origins')
options.origins.forEach(function (o) {
assert.ok(typeof o === 'string' || o instanceof RegExp, o +
' is not a valid origin');
});
assert.optionalBool(options.credentials, 'options.credentials');
assert.optionalArrayOfString(options.allowHeaders, 'options.allowHeaders');
assert.ok(typeof o === 'string' || o instanceof RegExp, o +
' is not a valid origin')
})
assert.optionalBool(options.credentials, 'options.credentials')
assert.optionalArrayOfString(options.allowHeaders, 'options.allowHeaders')
assert.optionalArrayOfString(options.exposeHeaders,
'options.exposeHeaders');
assert.optionalNumber(options.preflightMaxAge, 'options.preflightMaxAge');
'options.exposeHeaders')
assert.optionalNumber(options.preflightMaxAge, 'options.preflightMaxAge')
assert.optionalObject(options.preflightStrategy,
'options.preflightStrategy');
'options.preflightStrategy')
var opts = options;
var opts = options
opts.origins = options.origins || ['*']
opts.credentials = options.credentials || false;
opts.allowHeaders = options.allowHeaders || [];
opts.exposeHeaders = options.exposeHeaders || [];
opts.credentials = options.credentials || false
opts.allowHeaders = options.allowHeaders || []
opts.exposeHeaders = options.exposeHeaders || []
assert.ok(options.origins.indexOf('*') === -1 ||
options.credentials === false,
'credentials not supported with wildcard');
'credentials not supported with wildcard')
constants['EXPOSE_HEADERS'].forEach(function (h) {
if (opts.exposeHeaders.indexOf(h) === -1) {
opts.exposeHeaders.push(h);
}
});
if (opts.exposeHeaders.indexOf(h) === -1) {
opts.exposeHeaders.push(h)
}
})
constants['ALLOW_HEADERS'].forEach(function (h) {
if (opts.allowHeaders.indexOf(h) === -1) {
opts.allowHeaders.push(h);
}
});
if (opts.allowHeaders.indexOf(h) === -1) {
opts.allowHeaders.push(h)
}
})
return {
actual: actual.handler(opts),
preflight: preflight.handler(opts)
};
};
}
}

View file

@ -1,16 +1,16 @@
exports.match = function(incomingOrigin, origins) {
if(!incomingOrigin) {
return null;
}
exports.match = function (incomingOrigin, origins) {
if (!incomingOrigin) {
return null
}
for(var i = 0; i < origins.length; i++) {
var origin = origins[i];
if( (origin instanceof RegExp && origin.test(incomingOrigin)) ||
for (var i = 0; i < origins.length; i++) {
var origin = origins[i]
if ((origin instanceof RegExp && origin.test(incomingOrigin)) ||
(typeof origin === 'string' && origin === incomingOrigin) ||
(origin === '*')) {
return incomingOrigin;
}
return incomingOrigin
}
}
return null;
};
return null
}

View file

@ -1,46 +1,43 @@
var origin = require('./origin');
var constants = require('./constants.js');
var origin = require('./origin')
var constants = require('./constants.js')
exports.handler = function(options) {
return function(req, res, next) {
if (req.method !== 'OPTIONS') return next();
exports.handler = function (options) {
return function (req, res, next) {
if (req.method !== 'OPTIONS') return next()
// 6.2.1 and 6.2.2
var originHeader = req.headers['origin'];
if (origin.match(originHeader, options.origins) === false) return next();
var originHeader = req.headers['origin']
if (origin.match(originHeader, options.origins) === false) return next()
// 6.2.3
var requestedMethod = req.headers[constants['AC_REQ_METHOD']];
if (!requestedMethod) return next();
var requestedMethod = req.headers[constants['AC_REQ_METHOD']]
if (!requestedMethod) return next()
// 6.2.4
var requestedHeaders = req.headers[constants['AC_REQ_HEADERS']];
requestedHeaders = requestedHeaders ? requestedHeaders.split(', ') : [];
// var requestedHeaders = req.headers[constants['AC_REQ_HEADERS']]
// requestedHeaders = requestedHeaders ? requestedHeaders.split(', ') : []
var allowedMethods = [requestedMethod, 'OPTIONS'];
var allowedMethods = [requestedMethod, 'OPTIONS']
var allowedHeaders = constants['ALLOW_HEADERS']
.concat(options.allowHeaders);
.concat(options.allowHeaders)
res.once('header', function() {
res.once('header', function () {
// 6.2.7
res.header(constants['AC_ALLOW_ORIGIN'], originHeader);
res.header(constants['AC_ALLOW_CREDS'], true);
res.header(constants['AC_ALLOW_ORIGIN'], originHeader)
res.header(constants['AC_ALLOW_CREDS'], true)
// 6.2.8
if (options.preflightMaxAge) {
res.header(constants['AC_MAX_AGE'], options.preflightMaxAge);
res.header(constants['AC_MAX_AGE'], options.preflightMaxAge)
}
// 6.2.9
res.header(constants['AC_ALLOW_METHODS'], allowedMethods.join(', '));
res.header(constants['AC_ALLOW_METHODS'], allowedMethods.join(', '))
// 6.2.10
res.header(constants['AC_ALLOW_HEADERS'], allowedHeaders.join(', '));
res.header(constants['AC_ALLOW_HEADERS'], allowedHeaders.join(', '))
})
});
res.send(constants['HTTP_NO_CONTENT']);
};
};
res.send(constants['HTTP_NO_CONTENT'])
}
}

View file

@ -2,97 +2,96 @@
// Based on the spec at http://www.w3.org/TR/cors/
// The test numbers correspond to steps in the specification
//
/* eslint-env mocha */
var request = require('supertest');
var should = require('should');
var test = require('./test');
var request = require('supertest')
var should = require('should')
var test = require('./test')
describe('CORS: simple / actual requests', function() {
it('6.1.1 Does not set headers if Origin is missing', function(done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
});
request(server)
describe('CORS: simple / actual requests', function () {
it('6.1.1 Does not set headers if Origin is missing', function (done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
})
request(server)
.get('/test')
.expect(test.noHeader('access-control-allow-origin'))
.expect(200)
.end(done);
});
.end(done)
})
it('6.1.2 Does not set headers if Origin does not match', function(done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
});
request(server)
it('6.1.2 Does not set headers if Origin does not match', function (done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
})
request(server)
.get('/test')
.set('Origin', 'http://random-website.com')
.expect(test.noHeader('access-control-allow-origin'))
.expect(200)
.end(done);
});
.end(done)
})
it('6.1.3 Sets Allow-Origin headers if the Origin matches', function(done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
});
request(server)
it('6.1.3 Sets Allow-Origin headers if the Origin matches', function (done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
})
request(server)
.get('/test')
.set('Origin', 'http://api.myapp.com')
.expect('access-control-allow-origin', 'http://api.myapp.com')
.expect(200)
.end(done);
});
.end(done)
})
it('6.1.3 Does not set Access-Control-Allow-Credentials header if Origin is *', function(done) {
should.throws(function() {
var server = test.corsServer({
origins: ['*'],
credentials: true
});
});
done();
});
it('6.1.3 Sets Access-Control-Allow-Credentials header if configured', function(done) {
var server = test.corsServer({
origins: ['http://api.myapp.com'],
it('6.1.3 Does not set Access-Control-Allow-Credentials header if Origin is *', function (done) {
should.throws(function () {
test.corsServer({
origins: ['*'],
credentials: true
});
request(server)
})
})
done()
})
it('6.1.3 Sets Access-Control-Allow-Credentials header if configured', function (done) {
var server = test.corsServer({
origins: ['http://api.myapp.com'],
credentials: true
})
request(server)
.get('/test')
.set('Origin', 'http://api.myapp.com')
.expect('access-control-allow-credentials', 'true')
.expect(200)
.end(done);
});
.end(done)
})
it('6.1.4 Does not set exposed headers if empty', function(done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
});
request(server)
it('6.1.4 Does not set exposed headers if empty', function (done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
})
request(server)
.get('/test')
.set('Origin', 'http://api.myapp.com')
.expect('access-control-allow-origin', 'http://api.myapp.com')
.expect('access-control-expose-headers', /api-version/) // defaults
.expect(200)
.end(done);
});
.end(done)
})
it('6.1.4 Sets exposed headers if configured', function(done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com'],
exposeHeaders: ['HeaderA', 'HeaderB']
});
request(server)
it('6.1.4 Sets exposed headers if configured', function (done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com'],
exposeHeaders: ['HeaderA', 'HeaderB']
})
request(server)
.get('/test')
.set('Origin', 'http://api.myapp.com')
.expect('access-control-allow-origin', 'http://api.myapp.com')
.expect('access-control-expose-headers', /HeaderA, HeaderB/) // custom
.expect('access-control-expose-headers', /api-version/) // defaults
.expect(200)
.end(done);
});
});
.end(done)
})
})

View file

@ -2,65 +2,64 @@
// Based on the spec at http://www.w3.org/TR/cors/
// The test numbers correspond to steps in the specification
//
/* eslint-env mocha */
var request = require('supertest');
var should = require('should');
var test = require('./test');
var request = require('supertest')
var test = require('./test')
var METHOD_NOT_ALLOWED = 405;
var METHOD_NOT_ALLOWED = 405
describe('CORS: preflight requests', function() {
it('6.2.1 Does not set headers if Origin is missing', function(done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
});
request(server)
describe('CORS: preflight requests', function () {
it('6.2.1 Does not set headers if Origin is missing', function (done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
})
request(server)
.options('/test')
.expect(test.noHeader('access-control-allow-origin'))
.expect(METHOD_NOT_ALLOWED)
.end(done);
});
.end(done)
})
it('6.2.2 Does not set headers if Origin does not match', function(done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
});
request(server)
it('6.2.2 Does not set headers if Origin does not match', function (done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
})
request(server)
.options('/test')
.set('Origin', 'http://random-website.com')
.expect(test.noHeader('access-control-allow-origin'))
.expect(METHOD_NOT_ALLOWED)
.end(done);
});
.end(done)
})
it('6.2.3 Does not set headers if Access-Control-Request-Method is missing', function(done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
});
request(server)
it('6.2.3 Does not set headers if Access-Control-Request-Method is missing', function (done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
})
request(server)
.options('/test')
.set('Origin', 'http://api.myapp.com')
.expect(test.noHeader('access-control-allow-origin'))
.expect(test.noHeader('access-control-allow-methods'))
.expect(METHOD_NOT_ALLOWED)
.end(done);
});
.end(done)
})
xit('6.2.4 Does not terminate if parsing of Access-Control-Request-Headers fails', function(done) {
done();
});
xit('6.2.4 Does not terminate if parsing of Access-Control-Request-Headers fails', function (done) {
done()
})
xit('6.2.5 Always matches Access-Control-Request-Method (spec says it is acceptable)', function(done) {
done();
});
xit('6.2.5 Always matches Access-Control-Request-Method (spec says it is acceptable)', function (done) {
done()
})
it('6.2.6 Does not set headers if Access-Control-Request-Headers does not match', function(done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com'],
acceptHeaders: ['API-Token']
});
request(server)
it('6.2.6 Does not set headers if Access-Control-Request-Headers does not match', function (done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com'],
acceptHeaders: ['API-Token']
})
request(server)
.options('/test')
.set('Origin', 'http://api.myapp.com')
.set('Access-Control-Request-Headers', 'Weird-Header')
@ -68,55 +67,55 @@ describe('CORS: preflight requests', function() {
.expect(test.noHeader('access-control-allow-methods'))
.expect(test.noHeader('access-control-allow-headers'))
.expect(METHOD_NOT_ALLOWED)
.end(done);
});
.end(done)
})
it('6.2.7 Set the Allow-Origin header if it matches', function(done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
});
request(server)
it('6.2.7 Set the Allow-Origin header if it matches', function (done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
})
request(server)
.options('/test')
.set('Origin', 'http://api.myapp.com')
.set('Access-Control-Request-Method', 'GET')
.expect('Access-Control-Allow-Origin', 'http://api.myapp.com')
.expect(204)
.end(done);
});
.end(done)
})
it('6.2.8 Set the Access-Control-Max-Age header if a max age is provided', function(done) {
var server = test.corsServer({
preflightMaxAge: 5,
origins: ['http://api.myapp.com', 'http://www.myapp.com']
});
request(server)
it('6.2.8 Set the Access-Control-Max-Age header if a max age is provided', function (done) {
var server = test.corsServer({
preflightMaxAge: 5,
origins: ['http://api.myapp.com', 'http://www.myapp.com']
})
request(server)
.options('/test')
.set('Origin', 'http://api.myapp.com')
.set('Access-Control-Request-Method', 'GET')
.expect('Access-Control-Max-Age', '5')
.expect(204)
.end(done);
});
.end(done)
})
it('6.2.9 Set the Allow-Method header', function(done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
});
request(server)
it('6.2.9 Set the Allow-Method header', function (done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com']
})
request(server)
.options('/test')
.set('Origin', 'http://api.myapp.com')
.set('Access-Control-Request-Method', 'GET')
.expect('Access-Control-Allow-Methods', 'GET, OPTIONS')
.expect(204)
.end(done);
});
.end(done)
})
it('6.2.10 Set the Allow-Headers to all configured custom headers', function(done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com'],
allowHeaders: ['HeaderA']
});
request(server)
it('6.2.10 Set the Allow-Headers to all configured custom headers', function (done) {
var server = test.corsServer({
origins: ['http://api.myapp.com', 'http://www.myapp.com'],
allowHeaders: ['HeaderA']
})
request(server)
.options('/test')
.set('Origin', 'http://api.myapp.com')
.set('Access-Control-Request-Method', 'GET')
@ -124,7 +123,6 @@ describe('CORS: preflight requests', function() {
.expect('Access-Control-Allow-Headers', /x-api-version/) // restify defaults
.expect('Access-Control-Allow-Headers', /HeaderA/) // custom header
.expect(204)
.end(done);
});
});
.end(done)
})
})

View file

@ -1,31 +1,30 @@
var should = require('should');
var origin = require('../src/origin');
describe('Origin list', function() {
/* eslint-env mocha */
require('should')
var origin = require('../src/origin')
describe('Origin list', function () {
var list = [
'http://api.myapp.com',
'http://www.myapp.com'
];
]
it('returns null if the origin is not in the list', function() {
it('returns null if the origin is not in the list', function () {
var o = origin.match('http://random-website.com', list);
(o === null).should.eql(true);
});
(o === null).should.eql(true)
})
it('does not do partial matches', function() {
it('does not do partial matches', function () {
var o = origin.match('api.myapp.com', list);
(o === null).should.eql(true);
});
(o === null).should.eql(true)
})
it('returns the origin if it matched', function() {
var o = origin.match('http://api.myapp.com', list);
o.should.eql('http://api.myapp.com');
});
it('returns the origin if it matched', function () {
var o = origin.match('http://api.myapp.com', list)
o.should.eql('http://api.myapp.com')
})
it('returns the origin if the list contains *', function() {
var o = origin.match('http://random-website.com', ['*']);
o.should.eql('http://random-website.com');
});
});
it('returns the origin if the list contains *', function () {
var o = origin.match('http://random-website.com', ['*'])
o.should.eql('http://random-website.com')
})
})

View file

@ -1,24 +1,24 @@
var restify = require('restify');
var cors = require('../src/index');
var restify = require('restify')
var cors = require('../src/index')
exports.corsServer = function(corsConfig) {
var middleware = cors(corsConfig);
var server = restify.createServer();
server.pre(middleware.preflight);
server.use(middleware.actual);
server.get('/test', function(req, res, next) {
res.header('Custom-Response-Header', '123456');
res.header('Max-Age', 5*60*1000);
res.send(200, 'ok');
next();
});
return server;
};
exports.corsServer = function (corsConfig) {
var middleware = cors(corsConfig)
var server = restify.createServer()
server.pre(middleware.preflight)
server.use(middleware.actual)
server.get('/test', function (req, res, next) {
res.header('Custom-Response-Header', '123456')
res.header('Max-Age', 5 * 60 * 1000)
res.send(200, 'ok')
next()
})
return server
}
exports.noHeader = function(name) {
return function(res) {
exports.noHeader = function (name) {
return function (res) {
if (res.headers.hasOwnProperty(name)) {
return 'Should not have header ' + name;
return 'Should not have header ' + name
}
};
};
}
}