Comparing version 3.3.0 to 4.0.0
var Hapi = require('hapi'); | ||
var server = Hapi.createServer('127.0.0.1', 8000); | ||
var server = new Hapi.Server(); | ||
server.connection({ host: '127.0.0.1', port: 8000 }); | ||
// Add Crumb plugin | ||
server.pack.register({ plugin: require('../'), options: { restful: true } }, function(err) { | ||
if (err) throw err; | ||
server.register({ register: require('../'), options: { restful: true } }, function (err) { | ||
if (err) { | ||
throw err; | ||
} | ||
}); | ||
@@ -18,5 +22,6 @@ | ||
path: '/generate', | ||
handler: function(request) { | ||
handler: function (request, reply) { | ||
// return crumb if desired | ||
request.reply('{ "crumb": ' + request.plugins.crumb + ' }'); | ||
return reply('{ "crumb": ' + request.plugins.crumb + ' }'); | ||
} | ||
@@ -30,11 +35,12 @@ }, | ||
path: '/crumbed', | ||
handler: function(request) { | ||
request.reply('Crumb route'); | ||
handler: function (request, reply) { | ||
return reply('Crumb route'); | ||
} | ||
}, | ||
} | ||
]); | ||
server.start(function() { | ||
server.start(function () { | ||
console.log('Example restful server running at:', server.info.uri); | ||
}); | ||
}); |
var Hapi = require('hapi'); | ||
var serverOptions = { | ||
views: { | ||
path: __dirname + '/templates', | ||
engines: { | ||
html: require('handlebars') | ||
} | ||
var server = new Hapi.Server(); | ||
server.connection({ host: '127.0.0.1', port: 8000 }); | ||
server.views({ | ||
path: __dirname + '/templates', | ||
engines: { | ||
html: require('handlebars') | ||
} | ||
}; | ||
}); | ||
var server = new Hapi.Server('127.0.0.1', 8000, serverOptions); | ||
server.register({ register: require('../'), options: { cookieOptions: { isSecure: false } } }, function (err) { | ||
server.pack.register({ plugin: require('../'), options: { cookieOptions: { isSecure: false } } }, function (err) { | ||
if (err) throw err; | ||
if (err) { | ||
throw err; | ||
} | ||
}); | ||
@@ -22,2 +24,3 @@ | ||
handler: function (request, reply) { | ||
return reply.view('index', { title: 'test', message: 'hi' }); | ||
@@ -31,2 +34,3 @@ } | ||
handler: function (request, reply) { | ||
return reply.view('message', { title: 'test', message: request.payload.message }); | ||
@@ -37,3 +41,4 @@ } | ||
server.start(function () { | ||
console.log('Example server running at:', server.info.uri); | ||
}); |
@@ -1,1 +0,1 @@ | ||
module.exports = require('./lib'); | ||
module.exports = require('./lib'); |
304
lib/index.js
// Load modules | ||
var Hoek = require('hoek'); | ||
var Stream = require('stream'); | ||
var Boom = require('boom'); | ||
var Cryptiles = require('cryptiles'); | ||
var Hoek = require('hoek'); | ||
var Joi = require('joi'); | ||
var schema = require('./schema'); | ||
@@ -14,2 +14,15 @@ | ||
internals.schema = Joi.object().keys({ | ||
key: Joi.string().optional(), | ||
size: Joi.number().optional(), | ||
autoGenerate: Joi.boolean().optional(), | ||
addToViewContext: Joi.boolean().optional(), | ||
cookieOptions: Joi.object().keys(null), | ||
restful: Joi.boolean().optional(), | ||
skip: Joi.any().optional(), | ||
allowOrigins: Joi.array().excludes(Joi.string().valid('*')).optional() | ||
}); | ||
internals.defaults = { | ||
@@ -25,13 +38,137 @@ key: 'crumb', | ||
skip: false, // Set to a function which returns true when to skip crumb generation and validation | ||
allowOrigins: null // A list of CORS origins to set crumb cookie on. Defaults to server.settings.cors.origin | ||
allowOrigins: null // A list of CORS origins to set crumb cookie on. Defaults to request.route.settings.settings.cors.origin | ||
}; | ||
// Not used in restful mode | ||
internals.routeDefaults = { | ||
key: 'crumb', // query or payload key | ||
source: 'payload', // Crumb key source: 'payload', 'query' | ||
restful: false | ||
exports.register = function (server, options, next) { | ||
Joi.assert(options, internals.schema, 'Invalid crumb options'); | ||
var settings = Hoek.applyToDefaults(internals.defaults, options); | ||
var routeDefaults = { | ||
key: settings.key, | ||
restful: settings.resful, | ||
source: 'payload' | ||
}; | ||
server.state(settings.key, settings.cookieOptions); | ||
server.ext('onPostAuth', function (request, reply) { | ||
// If skip function enabled. Call it and if returns true, do not attempt to do anything with crumb. | ||
if (settings.skip && typeof settings.skip === 'function' && settings.skip(request, reply)) { | ||
return reply.continue(); | ||
} | ||
// Validate incoming crumb | ||
if (typeof request.route.settings.plugins._crumb === 'undefined') { | ||
if (request.route.settings.plugins.crumb || | ||
!request.route.settings.plugins.hasOwnProperty('crumb') && settings.autoGenerate) { | ||
request.route.settings.plugins._crumb = Hoek.applyToDefaults(routeDefaults, request.route.settings.plugins.crumb || {}); | ||
} | ||
else { | ||
request.route.settings.plugins._crumb = false; | ||
} | ||
} | ||
// Set crumb cookie and calculate crumb | ||
if ((settings.autoGenerate || | ||
request.route.settings.plugins._crumb) && | ||
(request.route.settings.cors ? internals.originParser(request.headers.origin, settings.allowOrigins || request.route.settings.cors.origin, request) : true)) { | ||
generate(request, reply); | ||
} | ||
// Validate crumb | ||
if (settings.restful === false || | ||
(!request.route.settings.plugins._crumb || request.route.settings.plugins._crumb.restful === false)) { | ||
if (request.method !== 'post' || | ||
!request.route.settings.plugins._crumb) { | ||
return reply.continue(); | ||
} | ||
var content = request[request.route.settings.plugins._crumb.source]; | ||
if (content instanceof Stream) { | ||
return reply(Boom.forbidden()); | ||
} | ||
if (content[request.route.settings.plugins._crumb.key] !== request.plugins.crumb) { | ||
return reply(Boom.forbidden()); | ||
} | ||
// Remove crumb | ||
delete request[request.route.settings.plugins._crumb.source][request.route.settings.plugins._crumb.key]; | ||
} | ||
else { | ||
if (request.method !== 'post' && request.method !== 'put' && request.method !== 'patch' && request.method !== 'delete' || | ||
!request.route.settings.plugins._crumb) { | ||
return reply.continue(); | ||
} | ||
var header = request.headers['x-csrf-token']; | ||
if (!header) { | ||
return reply(Boom.forbidden()); | ||
} | ||
if (header !== request.plugins.crumb) { | ||
return reply(Boom.forbidden()); | ||
} | ||
} | ||
return reply.continue(); | ||
}); | ||
server.ext('onPreResponse', function (request, reply) { | ||
// Add to view context | ||
var response = request.response; | ||
if (settings.addToViewContext && | ||
request.plugins.crumb && | ||
request.route.settings.plugins._crumb && | ||
!response.isBoom && | ||
response.variety === 'view') { | ||
response.source.context = response.source.context || {}; | ||
response.source.context[request.route.settings.plugins._crumb.key] = request.plugins.crumb; | ||
} | ||
return reply.continue(); | ||
}); | ||
var generate = function (request, reply) { | ||
var crumb = request.state[settings.key]; | ||
if (!crumb) { | ||
crumb = Cryptiles.randomString(settings.size); | ||
reply.state(settings.key, crumb, settings.cookieOptions); | ||
} | ||
request.plugins.crumb = crumb; | ||
return request.plugins.crumb; | ||
}; | ||
server.expose({ generate: generate }); | ||
return next(); | ||
}; | ||
exports.register.attributes = { | ||
pkg: require('../package.json') | ||
}; | ||
// Strip http or https from request host | ||
@@ -54,4 +191,5 @@ | ||
return this._host; | ||
} | ||
}; | ||
// Parses allowOrigin setting | ||
@@ -61,3 +199,3 @@ | ||
var host = internals.trimHost(request.server.info.uri); | ||
var host = internals.trimHost(request.connection.info.uri); | ||
var requestHost = internals.trimHost(request.headers.host); | ||
@@ -87,3 +225,3 @@ this._match = false; | ||
for (var i = 0, allowOriginsLen = allowOrigins.length; i < allowOriginsLen; i++) { | ||
for (var i = 0, il = allowOrigins.length; i < il; ++i) { | ||
if (allowOrigins[i] === '*') { | ||
@@ -101,4 +239,4 @@ return false; | ||
else { | ||
for (var ii = 0, allowOriginPartsLen = this._originAllowParts.length; ii < allowOriginPartsLen; ii++) { | ||
this._match = this._originAllowParts[ii] === '*' || this._originAllowParts[ii] === this._originParts[ii]; | ||
for (var j = 0, jl = this._originAllowParts.length; j < jl; ++j) { | ||
this._match = this._originAllowParts[j] === '*' || this._originAllowParts[j] === this._originParts[j]; | ||
if (!this._match) { | ||
@@ -113,142 +251,4 @@ break; | ||
} | ||
return this._match; | ||
} | ||
exports.register = function (plugin, options, next) { | ||
// Start with options validation | ||
Joi.validate(options, schema, { convert: false }, function (err, value) { | ||
if (err) { | ||
//plugin.hapi.error.internal('Invalid plugin options for crumb', err); | ||
return next('Invalid plugin options for crumb: ' + JSON.stringify(err)); | ||
} | ||
var settings = Hoek.applyToDefaults(internals.defaults, options); | ||
// copy the key and restful settings from internals.defaults to internals.routeDefaults for consistency | ||
internals.routeDefaults.key = settings.key; | ||
internals.routeDefaults.restful = settings.restful; | ||
plugin.state(settings.key, settings.cookieOptions); | ||
plugin.ext('onPostAuth', function (request, reply) { | ||
// If skip function enabled. Call it and if returns true, do not attempt to do anything with crumb. | ||
if (settings.skip && typeof settings.skip === 'function' && settings.skip(request, reply)) { | ||
return reply(); | ||
} | ||
// Validate incoming crumb | ||
if (typeof request.route.plugins._crumb === 'undefined') { | ||
if (request.route.plugins.crumb || | ||
!request.route.plugins.hasOwnProperty('crumb') && settings.autoGenerate) { | ||
request.route.plugins._crumb = Hoek.applyToDefaults(internals.routeDefaults, request.route.plugins.crumb || {}); | ||
} | ||
else { | ||
request.route.plugins._crumb = false; | ||
} | ||
} | ||
// Set crumb cookie and calculate crumb | ||
if ((settings.autoGenerate || | ||
request.route.plugins._crumb) && | ||
(request.server.settings.cors ? internals.originParser(request.headers.origin, settings.allowOrigins || request.server.settings.cors.origin, request) : true)) { | ||
generate(request, reply); | ||
} | ||
// Validate crumb | ||
if (settings.restful === false || | ||
(!request.route.plugins._crumb || request.route.plugins._crumb.restful === false)) { | ||
if (request.method !== 'post' || | ||
!request.route.plugins._crumb) { | ||
return reply(); | ||
} | ||
var content = request[request.route.plugins._crumb.source]; | ||
if (content instanceof Stream) { | ||
return reply(plugin.hapi.error.forbidden()); | ||
} | ||
if (content[request.route.plugins._crumb.key] !== request.plugins.crumb) { | ||
return reply(plugin.hapi.error.forbidden()); | ||
} | ||
// Remove crumb | ||
delete request[request.route.plugins._crumb.source][request.route.plugins._crumb.key]; | ||
} | ||
else { | ||
if (request.method !== 'post' && request.method !== 'put' && request.method !== 'patch' && request.method !== 'delete' || | ||
!request.route.plugins._crumb) { | ||
return reply(); | ||
} | ||
var header = request.headers['x-csrf-token']; | ||
if (!header) { | ||
return reply(plugin.hapi.error.forbidden()); | ||
} | ||
if (header !== request.plugins.crumb) { | ||
return reply(plugin.hapi.error.forbidden()); | ||
} | ||
} | ||
return reply(); | ||
}); | ||
plugin.ext('onPreResponse', function (request, reply) { | ||
// Add to view context | ||
var response = request.response; | ||
if (settings.addToViewContext && | ||
request.plugins.crumb && | ||
request.route.plugins._crumb && | ||
!response.isBoom && | ||
response.variety === 'view') { | ||
response.source.context = response.source.context || {}; | ||
response.source.context[request.route.plugins._crumb.key] = request.plugins.crumb; | ||
} | ||
return reply(); | ||
}); | ||
var generate = function (request, reply) { | ||
var crumb = request.state[settings.key]; | ||
if (!crumb) { | ||
crumb = Cryptiles.randomString(settings.size); | ||
reply.state(settings.key, crumb, settings.cookieOptions); | ||
} | ||
request.plugins.crumb = crumb; | ||
return request.plugins.crumb; | ||
}; | ||
plugin.expose({ generate: generate }); | ||
return next(); | ||
}); | ||
}; | ||
exports.register.attributes = { | ||
pkg: require('../package.json') | ||
}; |
{ | ||
"name": "crumb", | ||
"description": "CSRF crumb generation and validation plugin", | ||
"version": "3.3.0", | ||
"author": "Eran Hammer <eran@hammer.io> (http://hueniverse.com)", | ||
"contributors": [ | ||
"Marcus Stong <stongo@gmail.com>", | ||
"Nathan LaFreniere <quitlahok@gmail.com>", | ||
"Tom Steele <thomasjsteele@gmail.com>" | ||
], | ||
"version": "4.0.0", | ||
"repository": "git://github.com/hapijs/crumb", | ||
@@ -24,5 +18,6 @@ "bugs": { | ||
"engines": { | ||
"node": ">=0.10.30" | ||
"node": ">=0.10.32" | ||
}, | ||
"dependencies": { | ||
"boom": "2.x.x", | ||
"cryptiles": "2.x.x", | ||
@@ -33,8 +28,9 @@ "hoek": "2.x.x", | ||
"peerDependencies": { | ||
"hapi": ">=2.x.x" | ||
"hapi": ">=8.x.x" | ||
}, | ||
"devDependencies": { | ||
"hapi": "6.x.x", | ||
"code": "1.x.x", | ||
"handlebars": "1.3.x", | ||
"lab": "3.x.x" | ||
"hapi": "8.x.x", | ||
"lab": "5.x.x" | ||
}, | ||
@@ -41,0 +37,0 @@ "scripts": { |
// Load modules | ||
var Stream = require('stream'); | ||
var Code = require('code'); | ||
var Crumb = require('../'); | ||
var Hapi = require('hapi'); | ||
var Lab = require('lab'); | ||
var Hapi = require('hapi'); | ||
var Crumb = require('../'); | ||
var Stream = require('stream'); | ||
var Hoek = require('hoek'); | ||
@@ -17,7 +18,6 @@ | ||
var expect = Lab.expect; | ||
var before = Lab.before; | ||
var after = Lab.after; | ||
var describe = Lab.experiment; | ||
var it = Lab.test; | ||
var lab = exports.lab = Lab.script(); | ||
var describe = lab.describe; | ||
var it = lab.it; | ||
var expect = Code.expect; | ||
@@ -27,4 +27,8 @@ | ||
var options = { | ||
views: { | ||
it('returns view with crumb', function (done) { | ||
var server = new Hapi.Server(); | ||
server.connection(); | ||
server.views({ | ||
path: __dirname + '/templates', | ||
@@ -34,14 +38,10 @@ engines: { | ||
} | ||
} | ||
}; | ||
}); | ||
it('returns view with crumb', function (done) { | ||
var server1 = new Hapi.Server(options); | ||
server1.route([ | ||
server.route([ | ||
{ | ||
method: 'GET', path: '/1', handler: function (request, reply) { | ||
expect(request.plugins.crumb).to.exist; | ||
expect(request.server.plugins.crumb.generate).to.exist; | ||
expect(request.plugins.crumb).to.exist(); | ||
expect(request.server.plugins.crumb.generate).to.exist(); | ||
@@ -96,7 +96,8 @@ return reply.view('index', { | ||
server1.pack.register({ plugin: require('../'), options: { cookieOptions: { isSecure: true } } }, function (err) { | ||
server.register({ register: Crumb, options: { cookieOptions: { isSecure: true } } }, function (err) { | ||
expect(err).to.not.exist; | ||
server1.inject({ method: 'GET', url: '/1' }, function (res) { | ||
expect(err).to.not.exist(); | ||
server.inject({ method: 'GET', url: '/1' }, function (res) { | ||
expect(res.statusCode).to.equal(200); | ||
var header = res.headers['set-cookie']; | ||
@@ -109,15 +110,15 @@ expect(header.length).to.equal(1); | ||
server1.inject({ method: 'POST', url: '/2', payload: '{ "key": "value", "crumb": "' + cookie[1] + '" }', headers: { cookie: 'crumb=' + cookie[1] } }, function (res) { | ||
server.inject({ method: 'POST', url: '/2', payload: '{ "key": "value", "crumb": "' + cookie[1] + '" }', headers: { cookie: 'crumb=' + cookie[1] } }, function (res) { | ||
expect(res.result).to.equal('valid'); | ||
server1.inject({ method: 'POST', url: '/2', payload: '{ "key": "value", "crumb": "x' + cookie[1] + '" }', headers: { cookie: 'crumb=' + cookie[1] } }, function (res) { | ||
server.inject({ method: 'POST', url: '/2', payload: '{ "key": "value", "crumb": "x' + cookie[1] + '" }', headers: { cookie: 'crumb=' + cookie[1] } }, function (res) { | ||
expect(res.statusCode).to.equal(403); | ||
server1.inject({ method: 'POST', url: '/3', headers: { cookie: 'crumb=' + cookie[1] } }, function (res) { | ||
server.inject({ method: 'POST', url: '/3', headers: { cookie: 'crumb=' + cookie[1] } }, function (res) { | ||
expect(res.statusCode).to.equal(403); | ||
server1.inject({ method: 'GET', url: '/4' }, function (res) { | ||
server.inject({ method: 'GET', url: '/4' }, function (res) { | ||
@@ -135,7 +136,8 @@ expect(res.result).to.equal('<!DOCTYPE html><html><head><title>test</title></head><body><div><h1>hi</h1><h2></h2></div></body></html>'); | ||
TestStream.prototype._read = function() { | ||
TestStream.prototype._read = function () { | ||
var i = this._index++; | ||
if (i > this._max) | ||
if (i > this._max) { | ||
this.push(null); | ||
} | ||
else { | ||
@@ -148,7 +150,7 @@ var str = '' + i; | ||
server1.inject({ method: 'POST', url: '/5', payload: new TestStream(), headers: { 'content-type': 'application/octet-stream', 'content-disposition': 'attachment; filename="test.txt"' }, simulate: { end: true } }, function (res) { | ||
server.inject({ method: 'POST', url: '/5', payload: new TestStream(), headers: { 'content-type': 'application/octet-stream', 'content-disposition': 'attachment; filename="test.txt"' }, simulate: { end: true } }, function (res) { | ||
expect(res.statusCode).to.equal(403); | ||
server1.inject({method: 'GET', url: '/6'}, function(res) { | ||
server.inject({method: 'GET', url: '/6'}, function(res) { | ||
@@ -162,3 +164,3 @@ var header = res.headers['set-cookie']; | ||
server1.inject({method: 'GET', url: '/7'}, function(res) { | ||
server.inject({method: 'GET', url: '/7'}, function(res) { | ||
@@ -169,5 +171,5 @@ var cookie = res.headers['set-cookie'].toString(); | ||
var headers = {}; | ||
headers['Origin'] = '127.0.0.1'; | ||
headers.origin = '127.0.0.1'; | ||
server1.inject({method: 'GET', url: '/1', headers: headers}, function(res) { | ||
server.inject({method: 'GET', url: '/1', headers: headers}, function(res) { | ||
@@ -190,10 +192,19 @@ var cookie = res.headers['set-cookie'].toString(); | ||
it('Does not add crumb to view context when "addToViewContext" option set to false', function(done) { | ||
it('Does not add crumb to view context when "addToViewContext" option set to false', function (done) { | ||
var server2 = new Hapi.Server(options); | ||
server2.route({ | ||
var server = new Hapi.Server(); | ||
server.connection(); | ||
server.views({ | ||
path: __dirname + '/templates', | ||
engines: { | ||
html: require('handlebars') | ||
} | ||
}); | ||
server.route({ | ||
method: 'GET', path: '/1', handler: function (request, reply) { | ||
expect(request.plugins.crumb).to.exist; | ||
expect(request.server.plugins.crumb.generate).to.exist; | ||
expect(request.plugins.crumb).to.exist(); | ||
expect(request.server.plugins.crumb.generate).to.exist(); | ||
@@ -207,6 +218,6 @@ return reply.view('index', { | ||
server2.pack.register({ plugin: require('../'), options: { cookieOptions: { isSecure: true }, addToViewContext: false } }, function (err) { | ||
server.register({ register: Crumb, options: { cookieOptions: { isSecure: true }, addToViewContext: false } }, function (err) { | ||
expect(err).to.not.exist; | ||
server2.inject({ method: 'GET', url: '/1' }, function (res) { | ||
expect(err).to.not.exist(); | ||
server.inject({ method: 'GET', url: '/1' }, function (res) { | ||
@@ -219,10 +230,19 @@ expect(res.result).to.equal('<!DOCTYPE html><html><head><title>test</title></head><body><div><h1>hi</h1><h2></h2></div></body></html>'); | ||
it('Works without specifying plugin options', function(done) { | ||
it('Works without specifying plugin options', function (done) { | ||
var server3 = new Hapi.Server(options); | ||
server3.route({ | ||
var server = new Hapi.Server(); | ||
server.connection(); | ||
server.views({ | ||
path: __dirname + '/templates', | ||
engines: { | ||
html: require('handlebars') | ||
} | ||
}); | ||
server.route({ | ||
method: 'GET', path: '/1', handler: function (request, reply) { | ||
expect(request.plugins.crumb).to.exist; | ||
expect(request.server.plugins.crumb.generate).to.exist; | ||
expect(request.plugins.crumb).to.exist(); | ||
expect(request.server.plugins.crumb.generate).to.exist(); | ||
@@ -236,7 +256,7 @@ return reply.view('index', { | ||
server3.pack.register({ plugin: require('../'), options: null }, function (err) { | ||
server.register({ register: Crumb, options: null }, function (err) { | ||
expect(err).to.not.exist; | ||
expect(err).to.not.exist(); | ||
server3.inject({ method: 'GET', url: '/1' }, function (res) { | ||
server.inject({ method: 'GET', url: '/1' }, function (res) { | ||
@@ -254,6 +274,15 @@ var header = res.headers['set-cookie']; | ||
it('route uses crumb when route.config.plugins.crumb set to true and autoGenerate set to false', function(done) { | ||
it('route uses crumb when route.config.plugins.crumb set to true and autoGenerate set to false', function (done) { | ||
var server3 = new Hapi.Server(options); | ||
server3.route([ | ||
var server = new Hapi.Server(); | ||
server.connection(); | ||
server.views({ | ||
path: __dirname + '/templates', | ||
engines: { | ||
html: require('handlebars') | ||
} | ||
}); | ||
server.route([ | ||
{ | ||
@@ -264,3 +293,3 @@ method: 'GET', path: '/1', handler: function (request, reply) { | ||
expect(crumb).to.be.undefined; | ||
expect(crumb).to.not.exist(); | ||
@@ -280,9 +309,9 @@ return reply('bonjour'); | ||
server3.pack.register({ plugin: require('../'), options: { autoGenerate: false } }, function (err) { | ||
server.register({ register: Crumb, options: { autoGenerate: false } }, function (err) { | ||
expect(err).to.not.exist; | ||
expect(err).to.not.exist(); | ||
server3.inject({ method: 'GET', url: '/1' }, function (res) { | ||
server.inject({ method: 'GET', url: '/1' }, function (res) { | ||
server3.inject({ method: 'GET', url: '/2'}, function (res) { | ||
server.inject({ method: 'GET', url: '/2'}, function (res) { | ||
@@ -300,4 +329,6 @@ var header = res.headers['set-cookie']; | ||
it('does not validate crumb when "skip" option returns true', function (done) { | ||
var server6 = new Hapi.Server(); | ||
server6.route([ | ||
var server = new Hapi.Server(); | ||
server.connection(); | ||
server.route([ | ||
{ | ||
@@ -316,12 +347,12 @@ method: 'POST', path: '/1', handler: function (request, reply) { | ||
server6.pack.register({ plugin: require('../'), options: { skip: skip }}, function (err) { | ||
expect(err).to.not.exist; | ||
server.register({ register: Crumb, options: { skip: skip }}, function (err) { | ||
expect(err).to.not.exist(); | ||
var headers = {}; | ||
headers['X-API-Token'] = 'test'; | ||
server6.inject({ method: 'POST', url: '/1', headers: headers }, function (res) { | ||
server.inject({ method: 'POST', url: '/1', headers: headers }, function (res) { | ||
expect(res.statusCode).to.equal(200); | ||
var header = res.headers['set-cookie']; | ||
expect(header).to.not.contain('crumb'); | ||
expect(header).to.not.exist(); | ||
done(); | ||
@@ -333,4 +364,6 @@ }); | ||
it('ensures crumb validation when "skip" option is not a function', function (done) { | ||
var server6 = new Hapi.Server(); | ||
server6.route([ | ||
var server = new Hapi.Server(); | ||
server.connection(); | ||
server.route([ | ||
{ | ||
@@ -346,7 +379,7 @@ method: 'POST', path: '/1', handler: function (request, reply) { | ||
server6.pack.register({ plugin: require('../'), options: { skip: skip }}, function (err) { | ||
expect(err).to.not.exist; | ||
server.register({ register: Crumb, options: { skip: skip }}, function (err) { | ||
expect(err).to.not.exist(); | ||
var headers = {}; | ||
headers['X-API-Token'] = 'not-test'; | ||
server6.inject({ method: 'POST', url: '/1', headers: headers }, function (res) { | ||
server.inject({ method: 'POST', url: '/1', headers: headers }, function (res) { | ||
@@ -361,33 +394,27 @@ expect(res.statusCode).to.equal(403); | ||
it('does not allow "*" for allowOrigins setting', function (done) { | ||
var server7 = new Hapi.Server(); | ||
server7.pack.register({ plugin: require('../'), options: { allowOrigins: ['*'] } }, function (err) { | ||
var server = new Hapi.Server(); | ||
server.connection(); | ||
expect(err).to.exist; | ||
expect(function () { | ||
done(); | ||
}); | ||
server.register({ register: Crumb, options: { allowOrigins: ['*'] } }, function (err) {}); | ||
}).to.throw(/Invalid crumb options/); | ||
done(); | ||
}); | ||
it('does not set crumb cookie insecurely', function(done) { | ||
var options = { | ||
cors: true | ||
} | ||
var server4 = new Hapi.Server("localhost", options); | ||
server4.route([ | ||
{ | ||
method: 'GET', path: '/1', handler: function (request, reply) { | ||
it('does not set crumb cookie insecurely', function (done) { | ||
return reply('test'); | ||
} | ||
} | ||
]); | ||
server4.pack.register({ plugin: require('../'), options: null }, function (err) { | ||
var server = new Hapi.Server(); | ||
server.connection({ host: 'localhost', port: 80, routes: { cors: true } }); | ||
server.route({ method: 'GET', path: '/1', handler: function (request, reply) { return reply('test'); } }); | ||
expect(err).to.not.exist; | ||
server.register({ register: Crumb, options: null }, function (err) { | ||
expect(err).to.not.exist(); | ||
var headers = {}; | ||
headers['Host'] = 'http://localhost:80'; | ||
headers.host = 'http://localhost:80'; | ||
server4.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
@@ -397,10 +424,10 @@ var header = res.headers['set-cookie']; | ||
delete headers['Host']; | ||
delete headers.host; | ||
server4.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
headers['Origin'] = '127.0.0.1'; | ||
headers.origin = '127.0.0.1'; | ||
var header = res.headers['set-cookie']; | ||
expect(header).to.be.undefined; | ||
expect(header).to.not.exist(); | ||
@@ -413,5 +440,10 @@ done(); | ||
it('does not set crumb cookie insecurely using https', function(done) { | ||
it('does not set crumb cookie insecurely using https', function (done) { | ||
var options = { | ||
cors: true, | ||
host: 'localhost', | ||
port: 443, | ||
routes: { | ||
cors: true | ||
}, | ||
tls: { | ||
@@ -421,5 +453,7 @@ key: '-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA0UqyXDCqWDKpoNQQK/fdr0OkG4gW6DUafxdufH9GmkX/zoKz\ng/SFLrPipzSGINKWtyMvo7mPjXqqVgE10LDI3VFV8IR6fnART+AF8CW5HMBPGt/s\nfQW4W4puvBHkBxWSW1EvbecgNEIS9hTGvHXkFzm4xJ2e9DHp2xoVAjREC73B7JbF\nhc5ZGGchKw+CFmAiNysU0DmBgQcac0eg2pWoT+YGmTeQj6sRXO67n2xy/hA1DuN6\nA4WBK3wM3O4BnTG0dNbWUEbe7yAbV5gEyq57GhJIeYxRvveVDaX90LoAqM4cUH06\n6rciON0UbDHV2LP/JaH5jzBjUyCnKLLo5snlbwIDAQABAoIBAQDJm7YC3pJJUcxb\nc8x8PlHbUkJUjxzZ5MW4Zb71yLkfRYzsxrTcyQA+g+QzA4KtPY8XrZpnkgm51M8e\n+B16AcIMiBxMC6HgCF503i16LyyJiKrrDYfGy2rTK6AOJQHO3TXWJ3eT3BAGpxuS\n12K2Cq6EvQLCy79iJm7Ks+5G6EggMZPfCVdEhffRm2Epl4T7LpIAqWiUDcDfS05n\nNNfAGxxvALPn+D+kzcSF6hpmCVrFVTf9ouhvnr+0DpIIVPwSK/REAF3Ux5SQvFuL\njPmh3bGwfRtcC5d21QNrHdoBVSN2UBLmbHUpBUcOBI8FyivAWJhRfKnhTvXMFG8L\nwaXB51IZAoGBAP/E3uz6zCyN7l2j09wmbyNOi1AKvr1WSmuBJveITouwblnRSdvc\nsYm4YYE0Vb94AG4n7JIfZLKtTN0xvnCo8tYjrdwMJyGfEfMGCQQ9MpOBXAkVVZvP\ne2k4zHNNsfvSc38UNSt7K0HkVuH5BkRBQeskcsyMeu0qK4wQwdtiCoBDAoGBANF7\nFMppYxSW4ir7Jvkh0P8bP/Z7AtaSmkX7iMmUYT+gMFB5EKqFTQjNQgSJxS/uHVDE\nSC5co8WGHnRk7YH2Pp+Ty1fHfXNWyoOOzNEWvg6CFeMHW2o+/qZd4Z5Fep6qCLaa\nFvzWWC2S5YslEaaP8DQ74aAX4o+/TECrxi0z2lllAoGAdRB6qCSyRsI/k4Rkd6Lv\nw00z3lLMsoRIU6QtXaZ5rN335Awyrfr5F3vYxPZbOOOH7uM/GDJeOJmxUJxv+cia\nPQDflpPJZU4VPRJKFjKcb38JzO6C3Gm+po5kpXGuQQA19LgfDeO2DNaiHZOJFrx3\nm1R3Zr/1k491lwokcHETNVkCgYBPLjrZl6Q/8BhlLrG4kbOx+dbfj/euq5NsyHsX\n1uI7bo1Una5TBjfsD8nYdUr3pwWltcui2pl83Ak+7bdo3G8nWnIOJ/WfVzsNJzj7\n/6CvUzR6sBk5u739nJbfgFutBZBtlSkDQPHrqA7j3Ysibl3ZIJlULjMRKrnj6Ans\npCDwkQKBgQCM7gu3p7veYwCZaxqDMz5/GGFUB1My7sK0hcT7/oH61yw3O8pOekee\nuctI1R3NOudn1cs5TAy/aypgLDYTUGQTiBRILeMiZnOrvQQB9cEf7TFgDoRNCcDs\nV/ZWiegVB/WY7H0BkCekuq5bHwjgtJTpvHGqQ9YD7RhE8RSYOhdQ/Q==\n-----END RSA PRIVATE KEY-----\n', | ||
} | ||
} | ||
var server4 = new Hapi.Server("localhost", options); | ||
server4.route([ | ||
}; | ||
var server = new Hapi.Server(); | ||
server.connection(options); | ||
server.route([ | ||
{ | ||
@@ -432,23 +466,14 @@ method: 'GET', path: '/1', handler: function (request, reply) { | ||
]); | ||
server4.pack.register({ plugin: require('../'), options: null }, function (err) { | ||
server.register({ register: Crumb, options: null }, function (err) { | ||
expect(err).to.not.exist; | ||
expect(err).to.not.exist(); | ||
var headers = {}; | ||
headers['Host'] = 'https://localhost:443'; | ||
server.inject({ method: 'GET', url: '/1', headers: { host: 'https://localhost:443' } }, function (res) { | ||
server4.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
var header = res.headers['set-cookie']; | ||
expect(header[0]).to.contain('crumb'); | ||
delete headers['Host']; | ||
server.inject({ method: 'GET', url: '/1' }, function (res) { | ||
server4.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
headers['Origin'] = '127.0.0.1'; | ||
var header = res.headers['set-cookie']; | ||
expect(header).to.be.undefined; | ||
expect(res.headers['set-cookie']).to.not.exist(); | ||
done(); | ||
@@ -460,8 +485,7 @@ }); | ||
it('does set crumb cookie if allowOrigins set and CORS enabled', function(done) { | ||
var options = { | ||
cors: true | ||
} | ||
var server5 = new Hapi.Server(options); | ||
server5.route([ | ||
it('does set crumb cookie if allowOrigins set and CORS enabled', function (done) { | ||
var server = new Hapi.Server(); | ||
server.connection({ host: 'localhost', port: 80, routes: { cors: true } }); | ||
server.route([ | ||
{ | ||
@@ -474,7 +498,7 @@ method: 'GET', path: '/1', handler: function (request, reply) { | ||
]); | ||
server5.pack.register({ plugin: require('../'), options: { allowOrigins: ['127.0.0.1']} }, function (err) { | ||
expect(err).to.not.exist; | ||
server.register({ register: Crumb, options: { allowOrigins: ['127.0.0.1']} }, function (err) { | ||
expect(err).to.not.exist(); | ||
var headers = {}; | ||
headers['Origin'] = '127.0.0.1'; | ||
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
headers.origin = '127.0.0.1'; | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
@@ -484,22 +508,22 @@ var header = res.headers['set-cookie']; | ||
headers['Origin'] = '127.0.0.2'; | ||
headers.origin = '127.0.0.2'; | ||
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
var header = res.headers['set-cookie']; | ||
expect(header).to.be.undefined; | ||
expect(header).to.not.exist(); | ||
headers['Origin'] = '127.0.0.1:2000'; | ||
headers.origin = '127.0.0.1:2000'; | ||
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
var header = res.headers['set-cookie']; | ||
expect(header).to.be.undefined; | ||
expect(header).to.not.exist(); | ||
delete headers['Origin']; | ||
delete headers.origin; | ||
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
var header = res.headers['set-cookie']; | ||
expect(header).to.be.undefined; | ||
expect(header).to.not.exist(); | ||
@@ -514,10 +538,7 @@ done(); | ||
it('does set crumb cookie if allowOrigins not set and CORS enabled with server.settings.cors.origin set', function(done) { | ||
var options = { | ||
cors: { | ||
origin: ['127.0.0.1'] | ||
} | ||
} | ||
var server5 = new Hapi.Server(options); | ||
server5.route([ | ||
it('does set crumb cookie if allowOrigins not set and CORS enabled with server.settings.cors.origin set', function (done) { | ||
var server = new Hapi.Server(); | ||
server.connection({ host: 'localhost', port: 80, routes: { cors: { origin: ['127.0.0.1'] } } }); | ||
server.route([ | ||
{ | ||
@@ -530,7 +551,7 @@ method: 'GET', path: '/1', handler: function (request, reply) { | ||
]); | ||
server5.pack.register({ plugin: require('../'), options: null }, function (err) { | ||
expect(err).to.not.exist; | ||
server.register({ register: Crumb, options: null }, function (err) { | ||
expect(err).to.not.exist(); | ||
var headers = {}; | ||
headers['Origin'] = '127.0.0.1'; | ||
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
headers.origin = '127.0.0.1'; | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
@@ -540,22 +561,22 @@ var header = res.headers['set-cookie']; | ||
headers['Origin'] = '127.0.0.2'; | ||
headers.origin = '127.0.0.2'; | ||
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
var header = res.headers['set-cookie']; | ||
expect(header).to.be.undefined; | ||
expect(header).to.not.exist(); | ||
headers['Origin'] = '127.0.0.1:2000'; | ||
headers.origin = '127.0.0.1:2000'; | ||
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
var header = res.headers['set-cookie']; | ||
expect(header).to.be.undefined; | ||
expect(header).to.not.exist(); | ||
delete headers['Origin']; | ||
delete headers.origin; | ||
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
var header = res.headers['set-cookie']; | ||
expect(header).to.be.undefined; | ||
expect(header).to.not.exist(); | ||
@@ -570,11 +591,7 @@ done(); | ||
it('does not set crumb cookie if allowOrigins not set and CORS set to "*"', function(done) { | ||
it('does not set crumb cookie if allowOrigins not set and CORS set to "*"', function (done) { | ||
var options = { | ||
cors: { | ||
origin: ['*'] | ||
} | ||
} | ||
var server5 = new Hapi.Server(options); | ||
server5.route([ | ||
var server = new Hapi.Server(); | ||
server.connection({ host: 'localhost', port: 80, routes: { cors: { origin: ['*'] } } }); | ||
server.route([ | ||
{ | ||
@@ -588,10 +605,10 @@ method: 'GET', path: '/1', handler: function (request, reply) { | ||
server5.pack.register({ plugin: require('../'), options: null }, function (err) { | ||
expect(err).to.not.exist; | ||
server.register({ register: Crumb, options: null }, function (err) { | ||
expect(err).to.not.exist(); | ||
var headers = {}; | ||
headers['Origin'] = '127.0.0.1'; | ||
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
headers.origin = '127.0.0.1'; | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
var header = res.headers['set-cookie']; | ||
expect(header).to.be.undefined; | ||
expect(header).to.not.exist(); | ||
@@ -604,7 +621,6 @@ done(); | ||
it('checks port for allowOrigins setting', function (done) { | ||
var options = { | ||
cors: true | ||
} | ||
var server8 = new Hapi.Server(options); | ||
server8.route([ | ||
var server = new Hapi.Server(); | ||
server.connection({ host: 'localhost', port: 80, routes: { cors: true } }); | ||
server.route([ | ||
{ | ||
@@ -617,7 +633,7 @@ method: 'GET', path: '/1', handler: function (request, reply) { | ||
]); | ||
server8.pack.register({ plugin: require('../'), options: { allowOrigins: ['127.0.0.1:2000']} }, function (err) { | ||
expect(err).to.not.exist; | ||
server.register({ register: Crumb, options: { allowOrigins: ['127.0.0.1:2000']} }, function (err) { | ||
expect(err).to.not.exist(); | ||
var headers = {}; | ||
headers['Origin'] = '127.0.0.1:2000'; | ||
server8.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
headers.origin = '127.0.0.1:2000'; | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
@@ -627,13 +643,13 @@ var header = res.headers['set-cookie']; | ||
headers['Origin'] = '127.0.0.1:1000'; | ||
server8.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
headers.origin = '127.0.0.1:1000'; | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
var header = res.headers['set-cookie']; | ||
expect(header).to.be.undefined; | ||
expect(header).to.not.exist(); | ||
headers['Origin'] = '127.0.0.1'; | ||
server8.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
headers.origin = '127.0.0.1'; | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
var header = res.headers['set-cookie']; | ||
expect(header).to.be.undefined; | ||
expect(header).to.not.exist(); | ||
@@ -648,7 +664,6 @@ done(); | ||
it('parses wildcards in allowOrigins setting', function (done) { | ||
var options = { | ||
cors: true | ||
} | ||
var server9 = new Hapi.Server(options); | ||
server9.route([ | ||
var server = new Hapi.Server(); | ||
server.connection({ host: 'localhost', port: 80, routes: { cors: true } }); | ||
server.route([ | ||
{ | ||
@@ -661,7 +676,7 @@ method: 'GET', path: '/1', handler: function (request, reply) { | ||
]); | ||
server9.pack.register({ plugin: require('../'), options: { allowOrigins: ['127.0.0.1:*', '*.test.com']} }, function (err) { | ||
expect(err).to.not.exist; | ||
server.register({ register: Crumb, options: { allowOrigins: ['127.0.0.1:*', '*.test.com']} }, function (err) { | ||
expect(err).to.not.exist(); | ||
var headers = {}; | ||
headers['Origin'] = '127.0.0.1:2000'; | ||
server9.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
headers.origin = '127.0.0.1:2000'; | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
@@ -671,4 +686,4 @@ var header = res.headers['set-cookie']; | ||
headers['Origin'] = 'foo.test.com'; | ||
server9.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
headers.origin = 'foo.test.com'; | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
@@ -678,12 +693,11 @@ //expect(header[0]).to.contain('crumb'); | ||
headers['Origin'] = 'foo.tesc.com'; | ||
headers.origin = 'foo.tesc.com'; | ||
server9.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) { | ||
var header = res.headers['set-cookie']; | ||
expect(header).to.be.undefined; | ||
expect(header).to.not.exist(); | ||
done(); | ||
}); | ||
}); | ||
@@ -690,0 +704,0 @@ }); |
// Load modules | ||
var Code = require('code'); | ||
var Crumb = require('../'); | ||
var Hapi = require('hapi'); | ||
var Lab = require('lab'); | ||
var Hapi = require('hapi'); | ||
var Crumb = require('../'); | ||
@@ -15,7 +16,6 @@ | ||
var expect = Lab.expect; | ||
var before = Lab.before; | ||
var after = Lab.after; | ||
var describe = Lab.experiment; | ||
var it = Lab.test; | ||
var lab = exports.lab = Lab.script(); | ||
var describe = lab.describe; | ||
var it = lab.it; | ||
var expect = Code.expect; | ||
@@ -27,13 +27,12 @@ | ||
var options = { | ||
views: { | ||
path: __dirname + '/templates', | ||
engines: { | ||
html: require('handlebars') | ||
} | ||
var server = new Hapi.Server(); | ||
server.connection(); | ||
server.views({ | ||
path: __dirname + '/templates', | ||
engines: { | ||
html: require('handlebars') | ||
} | ||
}; | ||
}); | ||
var server = new Hapi.Server(options); | ||
server.route([ | ||
@@ -43,4 +42,4 @@ { | ||
expect(request.plugins.crumb).to.exist; | ||
expect(request.server.plugins.crumb.generate).to.exist; | ||
expect(request.plugins.crumb).to.exist(); | ||
expect(request.server.plugins.crumb.generate).to.exist(); | ||
@@ -103,5 +102,5 @@ return reply.view('index', { | ||
server.pack.register({plugin: require('../'), options: { restful: true, cookieOptions: { isSecure: true } } }, function (err) { | ||
server.register({ register: Crumb, options: { restful: true, cookieOptions: { isSecure: true } } }, function (err) { | ||
expect(err).to.not.exist; | ||
expect(err).to.not.exist(); | ||
server.inject({ method: 'GET', url: '/1' }, function (res) { | ||
@@ -116,7 +115,7 @@ | ||
var validHeader = {}; | ||
validHeader['cookie'] = 'crumb=' + cookie[1]; | ||
validHeader.cookie = 'crumb=' + cookie[1]; | ||
validHeader['x-csrf-token'] = cookie[1]; | ||
var invalidHeader = {}; | ||
invalidHeader['cookie'] = 'crumb=' + cookie[1]; | ||
invalidHeader.cookie = 'crumb=' + cookie[1]; | ||
invalidHeader['x-csrf-token'] = 'x' + cookie[1]; | ||
@@ -188,3 +187,1 @@ | ||
}); | ||
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
114841
5
4
18
867
2
+ Addedboom@2.x.x