Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

statehood

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

statehood - npm Package Compare versions

Comparing version 1.2.0 to 2.0.0

2

CONTRIBUTING.md

@@ -13,5 +13,5 @@ # How to contribute

* Fork the repository on GitHub.
* Fix the issue ensuring that your code follows the [style guide](https://github.com/hapijs/hapi/blob/master/docs/Style.md).
* Fix the issue ensuring that your code follows the [style guide](https://github.com/hapijs/contrib/blob/master/Style.md).
* Add tests for your new code ensuring that you have 100% code coverage (we can help you reach 100% but will not merge without it).
* Run `npm test` to generate a report of test coverage
* [Pull requests](http://help.github.com/send-pull-requests/) should be made to the [master branch](https://github.com/hapijs/statehood/tree/master).
// Load modules
var Querystring = require('querystring');
var Boom = require('boom');
var Cryptiles = require('cryptiles');
var Hoek = require('hoek');
var Iron = require('iron');
var Items = require('items');
var Cryptiles = require('cryptiles');
var Boom = require('boom');
var Hoek = require('hoek');
var Joi = require('joi');
var Querystring = require('querystring');

@@ -16,15 +17,35 @@

internals.schema = Joi.object({
strictHeader: Joi.boolean(),
ignoreErrors: Joi.boolean(),
isSecure: Joi.boolean(),
isHttpOnly: Joi.boolean(),
path: Joi.string().allow(null),
domain: Joi.string().allow(null),
ttl: Joi.number().allow(null),
encoding: Joi.string().valid('base64json', 'base64', 'form', 'iron', 'none'),
sign: Joi.object({
password: [Joi.string(), Joi.binary(), Joi.object()],
integrity: Joi.object()
}),
iron: Joi.object(),
password: [Joi.string(), Joi.binary(), Joi.object()],
// Used by hapi
clearInvalid: Joi.boolean(),
autoValue: Joi.any(),
passThrough: Joi.boolean()
});
internals.defaults = {
global: {
strictHeader: true,
failAction: 'error', // 'error' bails on first error, other values ignored
},
cookie: {
isSecure: false,
isHttpOnly: false,
path: null,
domain: null,
ttl: null, // MSecs, 0 means remove
encoding: 'none' // options: 'base64json', 'base64', 'form', 'iron', 'none'
}
strictHeader: true, // Require an RFC 6265 compliant header format
ignoreErrors: false,
isSecure: false,
isHttpOnly: false,
path: null,
domain: null,
ttl: null, // MSecs, 0 means remove
encoding: 'none' // options: 'base64json', 'base64', 'form', 'iron', 'none'
};

@@ -35,4 +56,5 @@

this.settings = Hoek.applyToDefaults(internals.defaults.global, options || {});
this.cookieDefaults = Hoek.applyToDefaults(internals.defaults.cookie, this.settings);
this.settings = Hoek.applyToDefaults(internals.defaults, options || {});
Joi.assert(this.settings, internals.schema, 'Invalid state definition defaults');
this.cookies = {};

@@ -48,3 +70,6 @@ this.names = [];

this.cookies[name] = Hoek.applyToDefaults(this.cookieDefaults, options || {});
var settings = Hoek.applyToDefaults(this.settings, options || {});
Joi.assert(settings, internals.schema, 'Invalid state definition: ' + name);
this.cookies[name] = settings;
this.names.push(name);

@@ -80,4 +105,6 @@ };

exports.parse = function (cookies, definitions, next) {
internals.Definitions.prototype.parse = function (cookies, next) {
var self = this;
var state = {};

@@ -104,29 +131,26 @@ var names = [];

});
// Validate cookie header syntax
if (verify !== '' &&
definitions.settings.failAction === 'error') {
return next(Boom.badRequest('Bad cookie header'), null, {});
if (verify !== '') {
return next(Boom.badRequest('Invalid cookie header'), null, []);
}
// Fail action
// Collect errors
var invalids = {};
var failed = []; // All errors
var errored = []; // Unignored errors
var record = function (reason, name, value, definition) {
var shouldStop = function (error, name, value, definition) {
invalids[name] = {
var details = {
name: name,
value: value,
settings: definition,
reason: error.message
reason: typeof reason === 'string' ? reason : reason.message
};
if (definition.failAction === 'error') {
next(Boom.badRequest('Bad cookie value: ' + Hoek.escapeHtml(name)), null, invalids);
return true;
failed.push(details);
if (!definition.ignoreErrors) {
errored.push(details);
}
return false;
};

@@ -140,3 +164,3 @@

var value = state[name];
var definition = definitions.cookies[name] || definitions.cookieDefaults;
var definition = self.cookies[name] || self.settings;

@@ -147,5 +171,4 @@ // Validate cookie

if (!name.match(internals.validateRx.nameRx.strict)) {
if (shouldStop(Boom.badRequest('Invalid cookie name'), name, value, definition)) {
return; // shouldStop calls next()
}
record('Invalid cookie name', name, value, definition);
return nextName();
}

@@ -156,5 +179,4 @@

if (!values[v].match(internals.validateRx.valueRx.strict)) {
if (shouldStop(Boom.badRequest('Invalid cookie value'), name, value, definition)) {
return; // shouldStop calls next()
}
record('Invalid cookie value', name, value, definition);
return nextName();
}

@@ -177,6 +199,3 @@ }

if (err) {
if (shouldStop(err, name, value, definition)) {
return; // shouldStop calls next()
}
record(err, name, value, definition);
return nextName();

@@ -188,6 +207,3 @@ }

if (err) {
if (shouldStop(err, name, value, definition)) {
return; // shouldStop calls next()
}
record(err, name, value, definition);
return nextName();

@@ -212,6 +228,3 @@ }

if (err) {
if (shouldStop(err, name, value, definition)) {
return; // shouldStop calls next()
}
record(err, name, value, definition);
return nextName();

@@ -223,6 +236,3 @@ }

if (err) {
if (shouldStop(err, name, value, definition)) {
return; // shouldStop calls next()
}
record(err, name, value, definition);
return nextName();

@@ -244,5 +254,3 @@ }

// All cookies parsed
return next(null, parsed, invalids);
return next(errored.length ? Boom.badRequest('Invalid cookie value', errored) : null, parsed, failed);
});

@@ -275,3 +283,3 @@ };

if (sigParts.length !== 2) {
return next(Boom.badRequest('Bad signature format'));
return next(Boom.badRequest('Invalid signature format'));
}

@@ -291,3 +299,3 @@

if (!Cryptiles.fixedTimeComparison(mac.digest, hmac)) {
return next(Boom.badRequest('Bad hmac value'));
return next(Boom.badRequest('Invalid hmac value'));
}

@@ -341,5 +349,5 @@

exports.format = function (cookies, definitions, callback) {
internals.Definitions.prototype.format = function (cookies, callback) {
definitions = definitions || internals.empty;
var self = this;

@@ -361,3 +369,3 @@ if (!cookies ||

var base = definitions.cookies[cookie.name] || definitions.cookieDefaults;
var base = self.cookies[cookie.name] || self.settings;
var definition = cookie.options ? Hoek.applyToDefaults(base, cookie.options) : base;

@@ -537,2 +545,22 @@

internals.Definitions.prototype.passThrough = function (header, fallback) {
if (!this.names.length) {
return header;
}
var exclude = [];
for (var i = 0, il = this.names.length; i < il; ++i) {
var name = this.names[i];
var definition = this.cookies[name];
var passCookie = definition.passThrough !== undefined ? definition.passThrough : fallback;
if (!passCookie) {
exclude.push(name);
}
}
return exports.exclude(header, exclude);
};
exports.exclude = function (cookies, excludes) {

@@ -550,3 +578,3 @@

return verify === '' ? result : Boom.badRequest('Bad cookie header');
return verify === '' ? result : Boom.badRequest('Invalid cookie header');
};
{
"name": "statehood",
"description": "HTTP State Management Utilities",
"version": "1.2.0",
"version": "2.0.0",
"repository": "git://github.com/hapijs/statehood",

@@ -14,13 +14,15 @@ "main": "index",

"engines": {
"node": ">=0.10.30"
"node": ">=0.10.32"
},
"dependencies": {
"hoek": "2.x.x",
"boom": "2.x.x",
"items": "1.x.x",
"cryptiles": "2.x.x",
"iron": "2.x.x"
"boom": "2.x.x",
"cryptiles": "2.x.x",
"hoek": "2.x.x",
"iron": "2.x.x",
"items": "1.x.x",
"joi": "5.x.x"
},
"devDependencies": {
"lab": "4.x.x"
"code": "1.x.x",
"lab": "5.x.x"
},

@@ -27,0 +29,0 @@ "scripts": {

// Load modules
var Code = require('code');
var Cryptiles = require('cryptiles');
var Hoek = require('hoek');
var Iron = require('iron');
var Lab = require('lab');
var Iron = require('iron');
var Hoek = require('hoek');
var Cryptiles = require('cryptiles');
var Statehood = require('../');

@@ -19,29 +20,34 @@

var lab = exports.lab = Lab.script();
var before = lab.before;
var after = lab.after;
var describe = lab.describe;
var it = lab.it;
var expect = Lab.expect;
var expect = Code.expect;
describe('Statehood', function () {
describe('Definitions', function () {
describe('Definitions', function () {
describe('add()', function () {
it('generates with defaults', function (done) {
it('throws on missing name', function (done) {
var definitions = new Statehood.Definitions();
expect(definitions.settings).to.deep.equal({
strictHeader: true,
failAction: 'error'
});
expect(function () {
definitions.add();
}).to.throw('Invalid name');
done();
});
it('overrides failAction', function (done) {
it('uses defaults', function (done) {
var definitions = new Statehood.Definitions({ failAction: 'ignore' });
expect(definitions.settings).to.deep.equal({
var definitions = new Statehood.Definitions();
definitions.add('test');
expect(definitions.cookies.test).to.deep.equal({
strictHeader: true,
failAction: 'ignore'
ignoreErrors: false,
isSecure: false,
isHttpOnly: false,
path: null,
domain: null,
ttl: null,
encoding: 'none'
});

@@ -51,52 +57,12 @@ done();

it('overrides strictHeader', function (done) {
it('records name', function (done) {
var definitions = new Statehood.Definitions({ strictHeader: false });
expect(definitions.settings).to.deep.equal({
strictHeader: false,
failAction: 'error'
});
var definitions = new Statehood.Definitions();
definitions.add('test');
expect(definitions.names).to.deep.equal(['test']);
done();
});
describe('#add', function () {
it('throws on missing name', function (done) {
var definitions = new Statehood.Definitions();
expect(function () {
definitions.add();
}).to.throw('Invalid name');
done();
});
it('uses defaults', function (done) {
var definitions = new Statehood.Definitions();
definitions.add('test');
expect(definitions.cookies.test).to.deep.equal({
strictHeader: true,
failAction: 'error',
isSecure: false,
isHttpOnly: false,
path: null,
domain: null,
ttl: null,
encoding: 'none'
});
done();
});
it('records name', function (done) {
var definitions = new Statehood.Definitions();
definitions.add('test');
expect(definitions.names).to.deep.equal(['test']);
done();
});
});
});
describe('#parse', function () {
describe('parse()', function () {

@@ -106,5 +72,6 @@ it('parses cookie', function (done) {

var definitions = new Statehood.Definitions();
Statehood.parse('a=b', definitions, function (err, states, invalids) {
definitions.parse('a=b', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ a: 'b' });

@@ -118,5 +85,6 @@ done();

var definitions = new Statehood.Definitions({ strictHeader: false });
Statehood.parse('a="1; b="2"; c=3; d[1]=4', definitions, function (err, states, invalids) {
definitions.parse('a="1; b="2"; c=3; d[1]=4', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ a: '"1', b: '2', c: '3', 'd[1]': '4' });

@@ -130,5 +98,6 @@ done();

var definitions = new Statehood.Definitions();
Statehood.parse('a=', definitions, function (err, states, invalids) {
definitions.parse('a=', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ a: '' });

@@ -142,5 +111,6 @@ done();

var definitions = new Statehood.Definitions();
Statehood.parse('a=""', definitions, function (err, states, invalids) {
definitions.parse('a=""', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ a: '' });

@@ -154,5 +124,6 @@ done();

var definitions = new Statehood.Definitions();
Statehood.parse('a=;', definitions, function (err, states, invalids) {
definitions.parse('a=;', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ a: '' });

@@ -166,5 +137,6 @@ done();

var definitions = new Statehood.Definitions();
Statehood.parse('a=23', definitions, function (err, states, invalids) {
definitions.parse('a=23', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ a: '23' });

@@ -178,5 +150,6 @@ done();

var definitions = new Statehood.Definitions();
Statehood.parse('a=1; a=2', definitions, function (err, states, invalids) {
definitions.parse('a=1; a=2', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ a: ['1', '2'] });

@@ -190,5 +163,6 @@ done();

var definitions = new Statehood.Definitions();
Statehood.parse('a=1; b="2"; c=3', definitions, function (err, states, invalids) {
definitions.parse('a=1; b="2"; c=3', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ a: '1', b: '2', c: '3' });

@@ -202,5 +176,6 @@ done();

var definitions = new Statehood.Definitions();
Statehood.parse('a="1"; b="2"; c=3', definitions, function (err, states, invalids) {
definitions.parse('a="1"; b="2"; c=3', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ a: '1', b: '2', c: '3' });

@@ -214,5 +189,6 @@ done();

var definitions = new Statehood.Definitions();
Statehood.parse('A = b; b = c', definitions, function (err, states, invalids) {
definitions.parse('A = b; b = c', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ A: 'b', b: 'c' });

@@ -226,5 +202,6 @@ done();

var definitions = new Statehood.Definitions();
Statehood.parse('a="b=123456789&c=something"', definitions, function (err, states, invalids) {
definitions.parse('a="b=123456789&c=something"', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ a: 'b=123456789&c=something' });

@@ -238,5 +215,6 @@ done();

var definitions = new Statehood.Definitions();
Statehood.parse('a=%1;b=x', definitions, function (err, states, invalids) {
definitions.parse('a=%1;b=x', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ a: '%1', b: 'x' });

@@ -250,5 +228,6 @@ done();

var definitions = new Statehood.Definitions();
Statehood.parse('z=%20%22%2c%3b%2f', definitions, function (err, states, invalids) {
definitions.parse('z=%20%22%2c%3b%2f', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ z: '%20%22%2c%3b%2f' });

@@ -263,5 +242,6 @@ done();

definitions.add('a', { encoding: 'form' });
Statehood.parse('a="b=%p123456789"', definitions, function (err, states, invalids) {
definitions.parse('a="b=%p123456789"', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ a: { b: '%p123456789' } });

@@ -276,5 +256,6 @@ done();

definitions.add('a', { encoding: 'form' });
Statehood.parse('a="b=123456789&c=something%20else"', definitions, function (err, states, invalids) {
definitions.parse('a="b=123456789&c=something%20else"', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ a: { b: '123456789', c: 'something else' } });

@@ -289,5 +270,6 @@ done();

definitions.add('a', { encoding: 'base64' });
Statehood.parse('a=dGVzdA; a=dGVzdA', definitions, function (err, states, invalids) {
definitions.parse('a=dGVzdA; a=dGVzdA', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ a: ['test', 'test'] });

@@ -302,5 +284,6 @@ done();

definitions.add('a', { encoding: 'base64' });
Statehood.parse('a=dGVzdA; a=dGVzdA; a=dGVzdA', definitions, function (err, states, invalids) {
definitions.parse('a=dGVzdA; a=dGVzdA; a=dGVzdA', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ a: ['test', 'test', 'test'] });

@@ -315,5 +298,6 @@ done();

definitions.add('key', { encoding: 'base64' });
Statehood.parse('key=dGVzdA==', definitions, function (err, states, invalids) {
definitions.parse('key=dGVzdA==', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ key: 'test' });

@@ -328,5 +312,6 @@ done();

definitions.add('key', { encoding: 'base64' });
Statehood.parse('key=dGVzdA', definitions, function (err, states, invalids) {
definitions.parse('key=dGVzdA', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ key: 'test' });

@@ -341,5 +326,6 @@ done();

definitions.add('key', { encoding: 'none' });
Statehood.parse('key=dGVzdA', definitions, function (err, states, invalids) {
definitions.parse('key=dGVzdA', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ key: 'dGVzdA' });

@@ -354,5 +340,6 @@ done();

definitions.add('key', { encoding: 'base64json' });
Statehood.parse('key=eyJ0ZXN0aW5nIjoianNvbiJ9', definitions, function (err, states, invalids) {
definitions.parse('key=eyJ0ZXN0aW5nIjoianNvbiJ9', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ key: { testing: 'json' } });

@@ -367,5 +354,6 @@ done();

definitions.add('key', { encoding: 'iron', password: 'password' });
Statehood.parse('key=Fe26.2**f3fc42242467f7a97c042be866a32c1e7645045c2cc085124eadc66d25fc8395*URXpH8k-R0d4O5bnY23fRQ*uq9rd8ZzdjZqUrq9P2Ci0yZ-EEUikGzxTLn6QTcJ0bc**3880c0ac8bab054f529afec8660ebbbbc8050e192e39e5d622e7ac312b9860d0*r_g7N9kJYqXDrFlvOnuKpfpEWwrJLOKMXEI43LAGeFg', definitions, function (err, states, invalids) {
definitions.parse('key=Fe26.2**f3fc42242467f7a97c042be866a32c1e7645045c2cc085124eadc66d25fc8395*URXpH8k-R0d4O5bnY23fRQ*uq9rd8ZzdjZqUrq9P2Ci0yZ-EEUikGzxTLn6QTcJ0bc**3880c0ac8bab054f529afec8660ebbbbc8050e192e39e5d622e7ac312b9860d0*r_g7N9kJYqXDrFlvOnuKpfpEWwrJLOKMXEI43LAGeFg', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ key: { a: 1, b: 2, c: 3 } });

@@ -380,5 +368,6 @@ done();

definitions.add('key', { encoding: 'iron', password: 'password', iron: Iron.defaults });
Statehood.parse('key=Fe26.2**f3fc42242467f7a97c042be866a32c1e7645045c2cc085124eadc66d25fc8395*URXpH8k-R0d4O5bnY23fRQ*uq9rd8ZzdjZqUrq9P2Ci0yZ-EEUikGzxTLn6QTcJ0bc**3880c0ac8bab054f529afec8660ebbbbc8050e192e39e5d622e7ac312b9860d0*r_g7N9kJYqXDrFlvOnuKpfpEWwrJLOKMXEI43LAGeFg', definitions, function (err, states, invalids) {
definitions.parse('key=Fe26.2**f3fc42242467f7a97c042be866a32c1e7645045c2cc085124eadc66d25fc8395*URXpH8k-R0d4O5bnY23fRQ*uq9rd8ZzdjZqUrq9P2Ci0yZ-EEUikGzxTLn6QTcJ0bc**3880c0ac8bab054f529afec8660ebbbbc8050e192e39e5d622e7ac312b9860d0*r_g7N9kJYqXDrFlvOnuKpfpEWwrJLOKMXEI43LAGeFg', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ key: { a: 1, b: 2, c: 3 } });

@@ -393,5 +382,6 @@ done();

definitions.add('sid', { encoding: 'form', sign: { password: 'password' } });
Statehood.parse('sid=a=1&b=2&c=3%20x.2d75635d74c1a987f84f3ee7f3113b9a2ff71f89d6692b1089f19d5d11d140f8*xGhc6WvkE55V-TzucCl0NVFmbijeCwgs5Hf5tAVbSUo', definitions, function (err, states, invalids) {
definitions.parse('sid=a=1&b=2&c=3%20x.2d75635d74c1a987f84f3ee7f3113b9a2ff71f89d6692b1089f19d5d11d140f8*xGhc6WvkE55V-TzucCl0NVFmbijeCwgs5Hf5tAVbSUo', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ sid: { a: '1', b: '2', c: '3 x' } });

@@ -406,5 +396,6 @@ done();

definitions.add('sid', { encoding: 'form', sign: { password: 'password', integrity: Iron.defaults.integrity } });
Statehood.parse('sid=a=1&b=2&c=3%20x.2d75635d74c1a987f84f3ee7f3113b9a2ff71f89d6692b1089f19d5d11d140f8*xGhc6WvkE55V-TzucCl0NVFmbijeCwgs5Hf5tAVbSUo', definitions, function (err, states, invalids) {
definitions.parse('sid=a=1&b=2&c=3%20x.2d75635d74c1a987f84f3ee7f3113b9a2ff71f89d6692b1089f19d5d11d140f8*xGhc6WvkE55V-TzucCl0NVFmbijeCwgs5Hf5tAVbSUo', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ sid: { a: '1', b: '2', c: '3 x' } });

@@ -419,5 +410,6 @@ done();

definitions.add('a', { strictHeader: false });
Statehood.parse('a="1', definitions, function (err, states, invalids) {
definitions.parse('a="1', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(failed).to.have.length(0);
expect(states).to.deep.equal({ a: '"1' });

@@ -431,7 +423,8 @@ done();

var definitions = new Statehood.Definitions();
Statehood.parse('a="1; b="2"; c=3', definitions, function (err, states, invalids) {
definitions.parse('a="1; b="2"; c=3', function (err, states, failed) {
expect(err).to.exist;
expect(invalids).to.deep.equal({
a: {
expect(err).to.exist();
expect(err.data).to.deep.equal([
{
name: 'a',
value: '"1',

@@ -446,7 +439,10 @@ settings: {

strictHeader: true,
failAction: 'error'
ignoreErrors: false
},
reason: 'Invalid cookie value'
}
});
]);
expect(failed).to.deep.equal(err.data);
done();

@@ -458,8 +454,9 @@ });

var definitions = new Statehood.Definitions({ failAction: 'ignore' });
Statehood.parse('a="1; b="2"; c=3', definitions, function (err, states, invalids) {
var definitions = new Statehood.Definitions({ ignoreErrors: true });
definitions.parse('a="1; b="2"; c=3', function (err, states, failed) {
expect(err).to.not.exist;
expect(invalids).to.deep.equal({
a: {
expect(err).to.not.exist();
expect(failed).to.deep.equal([
{
name: 'a',
value: '"1',

@@ -474,7 +471,7 @@ settings: {

strictHeader: true,
failAction: 'ignore'
ignoreErrors: true
},
reason: 'Invalid cookie value'
}
});
]);
done();

@@ -487,6 +484,6 @@ });

var definitions = new Statehood.Definitions();
definitions.add('a', { failAction: 'ignore' });
Statehood.parse('a="1', definitions, function (err, states, invalids) {
definitions.add('a', { ignoreErrors: true });
definitions.parse('a="1', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
done();

@@ -499,7 +496,8 @@ });

var definitions = new Statehood.Definitions();
Statehood.parse('a@="1"; b="2"; c=3', definitions, function (err, states, invalids) {
definitions.parse('a@="1"; b="2"; c=3', function (err, states, failed) {
expect(err).to.exist;
expect(invalids).to.deep.equal({
'a@': {
expect(err).to.exist();
expect(err.data).to.deep.equal([
{
name: 'a@',
value: '1',

@@ -514,7 +512,7 @@ settings: {

strictHeader: true,
failAction: 'error'
ignoreErrors: false
},
reason: 'Invalid cookie name'
}
});
]);
done();

@@ -524,10 +522,11 @@ });

it('ignores failed parsing cookie (name)', function (done) {
it('fails parsing cookie (multiple)', function (done) {
var definitions = new Statehood.Definitions({ failAction: 'ignore' });
Statehood.parse('a@="1"; b="2"; c=3', definitions, function (err, states, invalids) {
var definitions = new Statehood.Definitions();
definitions.parse('a@="1"; b@="2"; c=3', function (err, states, failed) {
expect(err).to.not.exist;
expect(invalids).to.deep.equal({
'a@': {
expect(err).to.exist();
expect(err.data).to.deep.equal([
{
name: 'a@',
value: '1',

@@ -542,7 +541,22 @@ settings: {

strictHeader: true,
failAction: 'ignore'
ignoreErrors: false
},
reason: 'Invalid cookie name'
},
{
name: 'b@',
value: '2',
settings: {
isSecure: false,
isHttpOnly: false,
path: null,
domain: null,
ttl: null,
encoding: 'none',
strictHeader: true,
ignoreErrors: false
},
reason: 'Invalid cookie name'
}
});
]);
done();

@@ -552,10 +566,19 @@ });

it('ignores failed parsing cookie (name)', function (done) {
var definitions = new Statehood.Definitions({ ignoreErrors: true });
definitions.parse('a@="1"; b="2"; c=3', function (err, states, failed) {
expect(err).to.not.exist();
done();
});
});
it('fails parsing cookie (empty pair)', function (done) {
var definitions = new Statehood.Definitions();
Statehood.parse('a=1; b=2; c=3;;', definitions, function (err, states, invalids) {
definitions.parse('a=1; b=2; c=3;;', function (err, states, failed) {
expect(err).to.exist;
expect(err.message).to.equal('Bad cookie header');
expect(invalids).to.deep.equal({});
expect(err).to.exist();
expect(err.message).to.equal('Invalid cookie header');
done();

@@ -569,12 +592,13 @@ });

definitions.add('x', { encoding: 'base64json' });
Statehood.parse('x=XeyJ0ZXN0aW5nIjoianNvbiJ9', definitions, function (err, states, invalids) {
definitions.parse('x=XeyJ0ZXN0aW5nIjoianNvbiJ9', function (err, states, failed) {
expect(err).to.exist;
expect(err.message).to.equal('Bad cookie value: x');
expect(invalids).to.deep.equal({
x: {
expect(err).to.exist();
expect(err.message).to.equal('Invalid cookie value');
expect(err.data).to.deep.equal([
{
name: 'x',
value: 'XeyJ0ZXN0aW5nIjoianNvbiJ9',
settings: {
strictHeader: true,
failAction: 'error',
ignoreErrors: false,
isSecure: false,

@@ -589,3 +613,3 @@ isHttpOnly: false,

}
});
]);

@@ -598,7 +622,7 @@ done();

var definitions = new Statehood.Definitions({ failAction: 'ignore' });
var definitions = new Statehood.Definitions({ ignoreErrors: true });
definitions.add('x', { encoding: 'base64json' });
Statehood.parse('x=XeyJ0ZXN0aW5nIjoianNvbiJ9', definitions, function (err, states, invalids) {
definitions.parse('x=XeyJ0ZXN0aW5nIjoianNvbiJ9', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
done();

@@ -612,6 +636,6 @@ });

definitions.add('x', { encoding: 'base64json' });
Statehood.parse('x=XeyJ0ZXN0aW5nIjoianNvbiJ9; x=XeyJ0ZXN0aW5dnIjoianNvbiJ9', definitions, function (err, states, invalids) {
definitions.parse('x=XeyJ0ZXN0aW5nIjoianNvbiJ9; x=XeyJ0ZXN0aW5dnIjoianNvbiJ9', function (err, states, failed) {
expect(err).to.exist;
expect(err.message).to.equal('Bad cookie value: x');
expect(err).to.exist();
expect(err.message).to.equal('Invalid cookie value');
done();

@@ -623,7 +647,7 @@ });

var definitions = new Statehood.Definitions({ failAction: 'ignore' });
var definitions = new Statehood.Definitions({ ignoreErrors: true });
definitions.add('x', { encoding: 'base64json' });
Statehood.parse('x=XeyJ0ZXN0aW5nIjoianNvbiJ9; x=XeyJ0ZXN0aW5dnIjoianNvbiJ9', definitions, function (err, states, invalids) {
definitions.parse('x=XeyJ0ZXN0aW5nIjoianNvbiJ9; x=XeyJ0ZXN0aW5dnIjoianNvbiJ9', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
done();

@@ -637,6 +661,6 @@ });

definitions.add('key', { encoding: 'iron', password: 'password' });
Statehood.parse('key=Fe26.1**f3fc42242467f7a97c042be866a32c1e7645045c2cc085124eadc66d25fc8395*URXpH8k-R0d4O5bnY23fRQ*uq9rd8ZzdjZqUrq9P2Ci0yZ-EEUikGzxTLn6QTcJ0bc**3880c0ac8bab054f529afec8660ebbbbc8050e192e39e5d622e7ac312b9860d0*r_g7N9kJYqXDrFlvOnuKpfpEWwrJLOKMXEI43LAGeFg', definitions, function (err, states, invalids) {
definitions.parse('key=Fe26.1**f3fc42242467f7a97c042be866a32c1e7645045c2cc085124eadc66d25fc8395*URXpH8k-R0d4O5bnY23fRQ*uq9rd8ZzdjZqUrq9P2Ci0yZ-EEUikGzxTLn6QTcJ0bc**3880c0ac8bab054f529afec8660ebbbbc8050e192e39e5d622e7ac312b9860d0*r_g7N9kJYqXDrFlvOnuKpfpEWwrJLOKMXEI43LAGeFg', function (err, states, failed) {
expect(err).to.exist;
expect(err.message).to.equal('Bad cookie value: key');
expect(err).to.exist();
expect(err.message).to.equal('Invalid cookie value');
done();

@@ -650,6 +674,6 @@ });

definitions.add('key', { encoding: 'iron', password: 'passwordx' });
Statehood.parse('key=Fe26.2**f3fc42242467f7a97c042be866a32c1e7645045c2cc085124eadc66d25fc8395*URXpH8k-R0d4O5bnY23fRQ*uq9rd8ZzdjZqUrq9P2Ci0yZ-EEUikGzxTLn6QTcJ0bc**3880c0ac8bab054f529afec8660ebbbbc8050e192e39e5d622e7ac312b9860d0*r_g7N9kJYqXDrFlvOnuKpfpEWwrJLOKMXEI43LAGeFg', definitions, function (err, states, invalids) {
definitions.parse('key=Fe26.2**f3fc42242467f7a97c042be866a32c1e7645045c2cc085124eadc66d25fc8395*URXpH8k-R0d4O5bnY23fRQ*uq9rd8ZzdjZqUrq9P2Ci0yZ-EEUikGzxTLn6QTcJ0bc**3880c0ac8bab054f529afec8660ebbbbc8050e192e39e5d622e7ac312b9860d0*r_g7N9kJYqXDrFlvOnuKpfpEWwrJLOKMXEI43LAGeFg', function (err, states, failed) {
expect(err).to.exist;
expect(err.message).to.equal('Bad cookie value: key');
expect(err).to.exist();
expect(err.message).to.equal('Invalid cookie value');
done();

@@ -663,6 +687,6 @@ });

definitions.add('sid', { encoding: 'form', sign: {} });
Statehood.parse('sid=a=1&b=2&c=3%20x.2d75635d74c1a987f84f3ee7f3113b9a2ff71f89d6692b1089f19d5d11d140f8*khsb8lmkNJS-iljqDKZDMmd__2PcHBz7Ksrc-48gZ-0', definitions, function (err, states, invalids) {
definitions.parse('sid=a=1&b=2&c=3%20x.2d75635d74c1a987f84f3ee7f3113b9a2ff71f89d6692b1089f19d5d11d140f8*khsb8lmkNJS-iljqDKZDMmd__2PcHBz7Ksrc-48gZ-0', function (err, states, failed) {
expect(err).to.exist;
expect(err.message).to.equal('Bad cookie value: sid');
expect(err).to.exist();
expect(err.message).to.equal('Invalid cookie value');
done();

@@ -676,6 +700,6 @@ });

definitions.add('sid', { encoding: 'form', sign: { password: 'password' } });
Statehood.parse('sid=a=1&b=2&c=3%20x', definitions, function (err, states, invalids) {
definitions.parse('sid=a=1&b=2&c=3%20x', function (err, states, failed) {
expect(err).to.exist;
expect(err.message).to.equal('Bad cookie value: sid');
expect(err).to.exist();
expect(err.message).to.equal('Invalid cookie value');
done();

@@ -687,7 +711,7 @@ });

var definitions = new Statehood.Definitions({ failAction: 'ignore' });
var definitions = new Statehood.Definitions({ ignoreErrors: true });
definitions.add('sid', { encoding: 'form', sign: { password: 'password' } });
Statehood.parse('sid=a=1&b=2&c=3%20x', definitions, function (err, states, invalids) {
definitions.parse('sid=a=1&b=2&c=3%20x', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
done();

@@ -701,6 +725,6 @@ });

definitions.add('sid', { encoding: 'form', sign: { password: 'password' } });
Statehood.parse('sid=a=1&b=2&c=3%20x; sid=a=1&b=2&c=3%20x', definitions, function (err, states, invalids) {
definitions.parse('sid=a=1&b=2&c=3%20x; sid=a=1&b=2&c=3%20x', function (err, states, failed) {
expect(err).to.exist;
expect(err.message).to.equal('Bad cookie value: sid');
expect(err).to.exist();
expect(err.message).to.equal('Invalid cookie value');
done();

@@ -712,7 +736,7 @@ });

var definitions = new Statehood.Definitions({ failAction: 'ignore' });
var definitions = new Statehood.Definitions({ ignoreErrors: true });
definitions.add('sid', { encoding: 'form', sign: { password: 'password' } });
Statehood.parse('sid=a=1&b=2&c=3%20x; sid=a=1&b=2&c=3%20x', definitions, function (err, states, invalids) {
definitions.parse('sid=a=1&b=2&c=3%20x; sid=a=1&b=2&c=3%20x', function (err, states, failed) {
expect(err).to.not.exist;
expect(err).to.not.exist();
done();

@@ -726,6 +750,6 @@ });

definitions.add('sid', { encoding: 'form', sign: { password: 'password' } });
Statehood.parse('sid=a=1&b=2&c=3%20x.', definitions, function (err, states, invalids) {
definitions.parse('sid=a=1&b=2&c=3%20x.', function (err, states, failed) {
expect(err).to.exist;
expect(err.message).to.equal('Bad cookie value: sid');
expect(err).to.exist();
expect(err.message).to.equal('Invalid cookie value');
done();

@@ -739,6 +763,6 @@ });

definitions.add('sid', { encoding: 'form', sign: { password: 'password' } });
Statehood.parse('sid=a=1&b=2&c=3%20x.2d75635d74c1a987f84f3ee7f3113b9a2ff71f89d6692b1089f19d5d11d140f8', definitions, function (err, states, invalids) {
definitions.parse('sid=a=1&b=2&c=3%20x.2d75635d74c1a987f84f3ee7f3113b9a2ff71f89d6692b1089f19d5d11d140f8', function (err, states, failed) {
expect(err).to.exist;
expect(err.message).to.equal('Bad cookie value: sid');
expect(err).to.exist();
expect(err.message).to.equal('Invalid cookie value');
done();

@@ -752,6 +776,6 @@ });

definitions.add('sid', { encoding: 'form', sign: { password: 'password' } });
Statehood.parse('sid=a=1&b=2&c=3%20x.2d75635d74c1a987f84f3ee7f3113b9a2ff71f89d6692b1089f19d5d11d140f8*-Ghc6WvkE55V-TzucCl0NVFmbijeCwgs5Hf5tAVbSUo', definitions, function (err, states, invalids) {
definitions.parse('sid=a=1&b=2&c=3%20x.2d75635d74c1a987f84f3ee7f3113b9a2ff71f89d6692b1089f19d5d11d140f8*-Ghc6WvkE55V-TzucCl0NVFmbijeCwgs5Hf5tAVbSUo', function (err, states, failed) {
expect(err).to.exist;
expect(err.message).to.equal('Bad cookie value: sid');
expect(err).to.exist();
expect(err.message).to.equal('Invalid cookie value');
done();

@@ -762,9 +786,10 @@ });

describe('#format', function () {
describe('format()', function () {
it('skips an empty header', function (done) {
Statehood.format(null, null, function (err, header) {
var definitions = new Statehood.Definitions();
definitions.format(null, function (err, header) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header).to.deep.equal([]);

@@ -777,5 +802,6 @@ done();

Statehood.format([], null, function (err, header) {
var definitions = new Statehood.Definitions();
definitions.format([], function (err, header) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header).to.deep.equal([]);

@@ -788,6 +814,7 @@ done();

Statehood.format({ name: 'sid', value: 'fihfieuhr9384hf', options: { ttl: 3600, isSecure: true, isHttpOnly: true, path: '/', domain: 'example.com' } }, null, function (err, header) {
var definitions = new Statehood.Definitions();
definitions.format({ name: 'sid', value: 'fihfieuhr9384hf', options: { ttl: 3600, isSecure: true, isHttpOnly: true, path: '/', domain: 'example.com' } }, function (err, header) {
var expires = new Date(Date.now() + 3600);
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.equal('sid=fihfieuhr9384hf; Max-Age=3; Expires=' + expires.toUTCString() + '; Secure; HttpOnly; Domain=example.com; Path=/');

@@ -800,5 +827,6 @@ done();

Statehood.format({ name: 'sid', value: 'fihfieuhr9384hf', options: { ttl: null, isSecure: true, isHttpOnly: true, path: '/', domain: 'example.com' } }, null, function (err, header) {
var definitions = new Statehood.Definitions();
definitions.format({ name: 'sid', value: 'fihfieuhr9384hf', options: { ttl: null, isSecure: true, isHttpOnly: true, path: '/', domain: 'example.com' } }, function (err, header) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.equal('sid=fihfieuhr9384hf; Secure; HttpOnly; Domain=example.com; Path=/');

@@ -811,5 +839,6 @@ done();

Statehood.format({ name: 'sid', value: 'fihfieuhr9384hf', options: { ttl: 0, isSecure: true, isHttpOnly: true, path: '/', domain: 'example.com' } }, null, function (err, header) {
var definitions = new Statehood.Definitions();
definitions.format({ name: 'sid', value: 'fihfieuhr9384hf', options: { ttl: 0, isSecure: true, isHttpOnly: true, path: '/', domain: 'example.com' } }, function (err, header) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.equal('sid=fihfieuhr9384hf; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Secure; HttpOnly; Domain=example.com; Path=/');

@@ -822,6 +851,7 @@ done();

Statehood.format({ name: 'sid', options: { ttl: 3600, isSecure: true, isHttpOnly: true, path: '/', domain: 'example.com' } }, null, function (err, header) {
var definitions = new Statehood.Definitions();
definitions.format({ name: 'sid', options: { ttl: 3600, isSecure: true, isHttpOnly: true, path: '/', domain: 'example.com' } }, function (err, header) {
var expires = new Date(Date.now() + 3600);
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.equal('sid=; Max-Age=3; Expires=' + expires.toUTCString() + '; Secure; HttpOnly; Domain=example.com; Path=/');

@@ -836,6 +866,6 @@ done();

definitions.add('sid', { ttl: 3600, isSecure: true, isHttpOnly: true, path: '/', domain: 'example.com' });
Statehood.format({ name: 'sid', value: 'fihfieuhr9384hf' }, definitions, function (err, header) {
definitions.format({ name: 'sid', value: 'fihfieuhr9384hf' }, function (err, header) {
var expires = new Date(Date.now() + 3600);
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.equal('sid=fihfieuhr9384hf; Max-Age=3; Expires=' + expires.toUTCString() + '; Secure; HttpOnly; Domain=example.com; Path=/');

@@ -850,5 +880,5 @@ done();

definitions.add('sid', { encoding: 'base64' });
Statehood.format({ name: 'sid', value: 'fihfieuhr9384hf' }, definitions, function (err, header) {
definitions.format({ name: 'sid', value: 'fihfieuhr9384hf' }, function (err, header) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.equal('sid=ZmloZmlldWhyOTM4NGhm');

@@ -863,5 +893,5 @@ done();

definitions.add('sid', { encoding: 'base64json' });
Statehood.format({ name: 'sid', value: { a: 1, b: 2, c: 3 } }, definitions, function (err, header) {
definitions.format({ name: 'sid', value: { a: 1, b: 2, c: 3 } }, function (err, header) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.equal('sid=eyJhIjoxLCJiIjoyLCJjIjozfQ==');

@@ -880,5 +910,5 @@ done();

Statehood.format({ name: 'sid', value: bad }, definitions, function (err, header) {
definitions.format({ name: 'sid', value: bad }, function (err, header) {
expect(err).to.exist;
expect(err).to.exist();
done();

@@ -892,5 +922,5 @@ });

definitions.add('sid', { encoding: 'form' });
Statehood.format({ name: 'sid', value: { a: 1, b: 2, c: '3 x' } }, definitions, function (err, header) {
definitions.format({ name: 'sid', value: { a: 1, b: 2, c: '3 x' } }, function (err, header) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.equal('sid=a=1&b=2&c=3%20x');

@@ -916,5 +946,5 @@ done();

});
Statehood.format({ name: 'sid', value: { a: 1, b: 2, c: '3 x' } }, definitions, function (err, header) {
definitions.format({ name: 'sid', value: { a: 1, b: 2, c: '3 x' } }, function (err, header) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.equal('sid=a=1&b=2&c=3%20x.2d75635d74c1a987f84f3ee7f3113b9a2ff71f89d6692b1089f19d5d11d140f8*xGhc6WvkE55V-TzucCl0NVFmbijeCwgs5Hf5tAVbSUo');

@@ -941,5 +971,5 @@ done();

});
Statehood.format({ name: 'sid', value: { a: 1, b: 2, c: '3 x' } }, definitions, function (err, header) {
definitions.format({ name: 'sid', value: { a: 1, b: 2, c: '3 x' } }, function (err, header) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.equal('sid=a=1&b=2&c=3%20x.*4wjD4tIxyiNW-rC3xBqL56TxUbb_aQT5PMykruWlR0Q');

@@ -957,5 +987,5 @@ done();

});
Statehood.format({ name: 'sid', value: { a: 1, b: 2, c: '3 x' } }, definitions, function (err, header) {
definitions.format({ name: 'sid', value: { a: 1, b: 2, c: '3 x' } }, function (err, header) {
expect(err).to.exist;
expect(err).to.exist();
expect(err.message).to.equal('Failed to sign cookie (sid) value: Empty password');

@@ -970,5 +1000,5 @@ done();

definitions.add('sid', { encoding: 'iron', password: 'password' });
Statehood.format({ name: 'sid', value: { a: 1, b: 2, c: 3 } }, definitions, function (err, header) {
definitions.format({ name: 'sid', value: { a: 1, b: 2, c: 3 } }, function (err, header) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.have.string('sid=Fe26.2*');

@@ -983,5 +1013,5 @@ done();

definitions.add('sid', { encoding: 'iron', password: 'password', iron: Iron.defaults });
Statehood.format({ name: 'sid', value: { a: 1, b: 2, c: 3 } }, definitions, function (err, header) {
definitions.format({ name: 'sid', value: { a: 1, b: 2, c: 3 } }, function (err, header) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.have.string('sid=Fe26.2*');

@@ -996,5 +1026,5 @@ done();

definitions.add('sid', { encoding: 'iron', password: Cryptiles.randomBits(256), iron: Iron.defaults });
Statehood.format({ name: 'sid', value: { a: 1, b: 2, c: 3 } }, definitions, function (err, header) {
definitions.format({ name: 'sid', value: { a: 1, b: 2, c: 3 } }, function (err, header) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.have.string('sid=Fe26.2*');

@@ -1009,5 +1039,5 @@ done();

definitions.add('sid', { encoding: 'iron' });
Statehood.format({ name: 'sid', value: { a: 1, b: 2, c: 3 } }, definitions, function (err, header) {
definitions.format({ name: 'sid', value: { a: 1, b: 2, c: 3 } }, function (err, header) {
expect(err).to.exist;
expect(err).to.exist();
expect(err.message).to.equal('Failed to encode cookie (sid) value: Empty password');

@@ -1020,9 +1050,10 @@ done();

Statehood.format([
var definitions = new Statehood.Definitions();
definitions.format([
{ name: 'sid', value: 'fihfieuhr9384hf', options: { ttl: 3600, isSecure: true, isHttpOnly: true, path: '/', domain: 'example.com' } },
{ name: 'pid', value: 'xyz' }
], null, function (err, header) {
], function (err, header) {
var expires = new Date(Date.now() + 3600);
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.equal('sid=fihfieuhr9384hf; Max-Age=3; Expires=' + expires.toUTCString() + '; Secure; HttpOnly; Domain=example.com; Path=/');

@@ -1036,5 +1067,6 @@ expect(header[1]).to.equal('pid=xyz');

Statehood.format({ name: 's;id', value: 'fihfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: '/', domain: 'example.com' } }, null, function (err, header) {
var definitions = new Statehood.Definitions();
definitions.format({ name: 's;id', value: 'fihfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: '/', domain: 'example.com' } }, function (err, header) {
expect(err).to.exist;
expect(err).to.exist();
expect(err.message).to.equal('Invalid cookie name: s;id');

@@ -1048,5 +1080,5 @@ done();

var definitions = new Statehood.Definitions({ strictHeader: false });
Statehood.format({ name: 's;id', value: 'fihfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: '/', domain: 'example.com' } }, definitions, function (err, header) {
definitions.format({ name: 's;id', value: 'fihfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: '/', domain: 'example.com' } }, function (err, header) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.equal('s;id=fihfieuhr9384hf; Secure; Domain=example.com; Path=/');

@@ -1061,5 +1093,5 @@ done();

definitions.add('s;id', { strictHeader: false });
Statehood.format({ name: 's;id', value: 'fihfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: '/', domain: 'example.com' } }, definitions, function (err, header) {
definitions.format({ name: 's;id', value: 'fihfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: '/', domain: 'example.com' } }, function (err, header) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.equal('s;id=fihfieuhr9384hf; Secure; Domain=example.com; Path=/');

@@ -1072,5 +1104,6 @@ done();

Statehood.format({ name: 'sid', value: 'fi"hfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: '/', domain: 'example.com' } }, null, function (err, header) {
var definitions = new Statehood.Definitions();
definitions.format({ name: 'sid', value: 'fi"hfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: '/', domain: 'example.com' } }, function (err, header) {
expect(err).to.exist;
expect(err).to.exist();
expect(err.message).to.equal('Invalid cookie value: fi"hfieuhr9384hf');

@@ -1083,5 +1116,6 @@ done();

Statehood.format({ name: 'sid', value: {}, options: { isSecure: true, isHttpOnly: false, path: '/', domain: 'example.com' } }, null, function (err, header) {
var definitions = new Statehood.Definitions();
definitions.format({ name: 'sid', value: {}, options: { isSecure: true, isHttpOnly: false, path: '/', domain: 'example.com' } }, function (err, header) {
expect(err).to.exist;
expect(err).to.exist();
expect(err.message).to.equal('Invalid cookie value: [object Object]');

@@ -1095,5 +1129,5 @@ done();

var definitions = new Statehood.Definitions({ strictHeader: false });
Statehood.format({ name: 'sid', value: 'fi"hfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: '/', domain: 'example.com' } }, definitions, function (err, header) {
definitions.format({ name: 'sid', value: 'fi"hfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: '/', domain: 'example.com' } }, function (err, header) {
expect(err).to.not.exist;
expect(err).to.not.exist();
expect(header[0]).to.equal('sid=fi"hfieuhr9384hf; Secure; Domain=example.com; Path=/');

@@ -1106,5 +1140,6 @@ done();

Statehood.format({ name: 'sid', value: 'fihfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: '/', domain: '-example.com' } }, null, function (err, header) {
var definitions = new Statehood.Definitions();
definitions.format({ name: 'sid', value: 'fihfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: '/', domain: '-example.com' } }, function (err, header) {
expect(err).to.exist;
expect(err).to.exist();
expect(err.message).to.equal('Invalid cookie domain: -example.com');

@@ -1117,5 +1152,6 @@ done();

Statehood.format({ name: 'sid', value: 'fihfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: '/', domain: '1234567890123456789012345678901234567890123456789012345678901234567890.example.com' } }, null, function (err, header) {
var definitions = new Statehood.Definitions();
definitions.format({ name: 'sid', value: 'fihfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: '/', domain: '1234567890123456789012345678901234567890123456789012345678901234567890.example.com' } }, function (err, header) {
expect(err).to.exist;
expect(err).to.exist();
expect(err.message).to.equal('Cookie domain too long: 1234567890123456789012345678901234567890123456789012345678901234567890.example.com');

@@ -1128,5 +1164,6 @@ done();

Statehood.format({ name: 'sid', value: 'fihfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: '/', domain: '.12345678901234567890.example.com' } }, null, function (err, header) {
var definitions = new Statehood.Definitions();
definitions.format({ name: 'sid', value: 'fihfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: '/', domain: '.12345678901234567890.example.com' } }, function (err, header) {
expect(err).to.not.exist;
expect(err).to.not.exist();
done();

@@ -1138,5 +1175,6 @@ });

Statehood.format({ name: 'sid', value: 'fihfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: 'd', domain: 'example.com' } }, null, function (err, header) {
var definitions = new Statehood.Definitions();
definitions.format({ name: 'sid', value: 'fihfieuhr9384hf', options: { isSecure: true, isHttpOnly: false, path: 'd', domain: 'example.com' } }, function (err, header) {
expect(err).to.exist;
expect(err).to.exist();
expect(err.message).to.equal('Invalid cookie path: d');

@@ -1148,28 +1186,49 @@ done();

describe('#prepareValue', function () {
describe('passThrough()', function () {
it('throws when missing options', function (done) {
it('returns header unchanged', function (done) {
expect(function () {
var definitions = new Statehood.Definitions();
var header = 'a=4;b=5;c=6';
var result = definitions.passThrough(header);
expect(result).to.equal(header);
done();
});
Statehood.prepareValue('name', 'value');
}).to.throw('Missing or invalid options');
it('returns header excluding local', function (done) {
var definitions = new Statehood.Definitions();
definitions.add('b');
var header = 'a=4;b=5;c=6';
var result = definitions.passThrough(header);
expect(result).to.equal('a=4;c=6');
done();
});
});
describe('#exclude', function () {
it('returns header including local (fallback)', function (done) {
it('returns all keys', function (done) {
var definitions = new Statehood.Definitions();
definitions.add('b');
var header = 'a=4;b=5;c=6';
var result = definitions.passThrough(header, true);
expect(result).to.equal('a=4;b=5;c=6');
done();
});
it('returns header including local (state option)', function (done) {
var definitions = new Statehood.Definitions();
definitions.add('b', { passThrough: true });
var header = 'a=4;b=5;c=6';
var result = Statehood.exclude(header, []);
expect(result).to.equal(header);
var result = definitions.passThrough(header);
expect(result).to.equal('a=4;b=5;c=6');
done();
});
it('returns keys without excluded', function (done) {
it('returns header including local (state option with fallback)', function (done) {
var definitions = new Statehood.Definitions();
definitions.add('b', { passThrough: false });
var header = 'a=4;b=5;c=6';
var result = Statehood.exclude(header, ['b']);
var result = definitions.passThrough(header, true);
expect(result).to.equal('a=4;c=6');

@@ -1179,10 +1238,52 @@ done();

it('returns error on invalid header', function (done) {
it('errors on invalid header', function (done) {
var header = 'a';
var result = Statehood.exclude(header, ['b']);
expect(result.message).to.equal('Bad cookie header');
var definitions = new Statehood.Definitions();
definitions.add('b');
var header = 'a=4;b=5;c=6;;';
var result = definitions.passThrough(header);
expect(result.message).to.equal('Invalid cookie header');
done();
});
});
});
});
describe('prepareValue()', function () {
it('throws when missing options', function (done) {
expect(function () {
Statehood.prepareValue('name', 'value');
}).to.throw('Missing or invalid options');
done();
});
});
describe('exclude()', function () {
it('returns all keys', function (done) {
var header = 'a=4;b=5;c=6';
var result = Statehood.exclude(header, []);
expect(result).to.equal(header);
done();
});
it('returns keys without excluded', function (done) {
var header = 'a=4;b=5;c=6';
var result = Statehood.exclude(header, ['b']);
expect(result).to.equal('a=4;c=6');
done();
});
it('returns error on invalid header', function (done) {
var header = 'a';
var result = Statehood.exclude(header, ['b']);
expect(result.message).to.equal('Invalid cookie header');
done();
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc