From 9b478881e41105dfe4d97e6512f1c48fbeaa3b0e Mon Sep 17 00:00:00 2001 From: Public Keating Date: Fri, 13 May 2011 09:30:22 -0600 Subject: [PATCH 1/9] Code cleanup to keep jslint from complaining. No functional changes. --- lib/cookie-sessions.js | 79 ++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/lib/cookie-sessions.js b/lib/cookie-sessions.js index bc14262..0452adf 100644 --- a/lib/cookie-sessions.js +++ b/lib/cookie-sessions.js @@ -1,7 +1,20 @@ +/*globals escape unescape */ + var crypto = require('crypto'); var url = require('url'); -var exports = module.exports = function(settings){ + +// Extend a given object with all the properties in passed-in object(s). +// From underscore.js (http://documentcloud.github.com/underscore/) +function extend(obj) { + Array.prototype.slice.call(arguments).forEach(function(source) { + for (var prop in source) obj[prop] = source[prop]; + }); + return obj; +} + +var exports; +exports = module.exports = function(settings){ var default_settings = { // don't set a default cookie secret, must be explicitly defined @@ -12,12 +25,13 @@ var exports = module.exports = function(settings){ var s = extend(default_settings, settings); if(!s.secret) throw new Error('No secret set in cookie-session settings'); - if(typeof s.path !== 'string' || s.path.indexOf('/') != 0) + if(typeof s.path !== 'string' || s.path.indexOf('/') !== 0) { throw new Error('invalid cookie path, must start with "/"'); + } return function(req, res, next){ // if the request is not under the specified path, do nothing. - if (url.parse(req.url).pathname.indexOf(s.path) != 0) { + if (url.parse(req.url).pathname.indexOf(s.path) !== 0) { next(); return; } @@ -57,19 +71,19 @@ var exports = module.exports = function(settings){ + '; expires=' + exports.expires(s.timeout) + '; path=' + s.path + '; HttpOnly'; } - + if (cookiestr !== undefined) { - if(Array.isArray(headers)) headers.push(['Set-Cookie', cookiestr]); - else { + if(Array.isArray(headers)) { + headers.push(['Set-Cookie', cookiestr]); + } else { // if a Set-Cookie header already exists, convert headers to // array so we can send multiple Set-Cookie headers. - if(headers['Set-Cookie'] !== undefined){ + if (headers['Set-Cookie'] !== undefined) { headers = exports.headersToArray(headers); headers.push(['Set-Cookie', cookiestr]); - } - // if no Set-Cookie header exists, leave the headers as an - // object, and add a Set-Cookie property - else { + } else { + // if no Set-Cookie header exists, leave the headers as an + // object, and add a Set-Cookie property headers['Set-Cookie'] = cookiestr; } } @@ -81,7 +95,7 @@ var exports = module.exports = function(settings){ } // call the original writeHead on the request return _writeHead.apply(res, args); - } + }; next(); }; @@ -95,16 +109,6 @@ exports.headersToArray = function(headers){ }, []); }; - -// Extend a given object with all the properties in passed-in object(s). -// From underscore.js (http://documentcloud.github.com/underscore/) -function extend(obj) { - Array.prototype.slice.call(arguments).forEach(function(source) { - for (var prop in source) obj[prop] = source[prop]; - }); - return obj; -}; - exports.deserialize = function(secret, timeout, str){ // Parses a secure cookie string, returning the object stored within it. // Throws an exception if the secure cookie string does not validate. @@ -121,7 +125,7 @@ exports.serialize = function(secret, data){ var data_str = JSON.stringify(data); var data_enc = exports.encrypt(secret, data_str); - var timestamp = (new Date()).getTime(); + var timestamp = new Date().getTime(); var hmac_sig = exports.hmac_signature(secret, timestamp, data_enc); var result = hmac_sig + timestamp + data_enc; if(!exports.checkLength(result)){ @@ -184,21 +188,20 @@ exports.readCookies = function(req){ // will already contain the parsed cookies if (req.cookies) { return req.cookies; + } else { + // Extracts the cookies from a request object. + var cookie = req.headers.cookie; + if(!cookie){ + return {}; } - else { - // Extracts the cookies from a request object. - var cookie = req.headers.cookie; - if(!cookie){ - return {}; - } - var parts = cookie.split(/\s*;\s*/g).map(function(x){ - return x.split('='); - }); - return parts.reduce(function(a, x){ - a[unescape(x[0])] = unescape(x[1]); - return a; - }, {}); - } + var parts = cookie.split(/\s*;\s*/g).map(function(x){ + return x.split('='); + }); + return parts.reduce(function(a, x){ + a[unescape(x[0])] = unescape(x[1]); + return a; + }, {}); + } }; exports.readSession = function(key, secret, timeout, req){ @@ -214,5 +217,5 @@ exports.readSession = function(key, secret, timeout, req){ exports.expires = function(timeout){ - return (new Date(new Date().getTime() + (timeout))).toUTCString(); + return new Date(new Date().getTime() + (timeout)).toUTCString(); }; From 292749be0b749a5250c7fd7901591035a3dc3834 Mon Sep 17 00:00:00 2001 From: Public Keating Date: Fri, 13 May 2011 10:12:26 -0600 Subject: [PATCH 2/9] I added a few options for tuning the cookies. You can now set the 'domain' and make the cookie 'secure' as well as 'max-age' will be sent if useMaxAge is true. Just to be complete, I made it so that you could also selectively turn on/off setting 'expires' and 'HttpOnly' with useExpires and useHttpOnly options, but the defaults shouldn't change any existing uses of cookie-sessions, except that useMaxAge is true by default. --- lib/cookie-sessions.js | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/cookie-sessions.js b/lib/cookie-sessions.js index 0452adf..e53f894 100644 --- a/lib/cookie-sessions.js +++ b/lib/cookie-sessions.js @@ -19,8 +19,13 @@ exports = module.exports = function(settings){ var default_settings = { // don't set a default cookie secret, must be explicitly defined session_key: '_node', - timeout: 1000 * 60 * 60 * 24, // 24 hours - path: '/' + timeout: 60 * 60 * 24, // 24 hours in seconds + path: '/', + domain: null, + secure: false, + useMaxAge: true, + useExpires: true, + useHttpOnly: true }; var s = extend(default_settings, settings); if(!s.secret) throw new Error('No secret set in cookie-session settings'); @@ -61,19 +66,22 @@ exports = module.exports = function(settings){ var cookiestr; if (req.session === undefined) { if ("cookie" in req.headers) { - cookiestr = escape(s.session_key) + '=' - + '; expires=' + exports.expires(0) - + '; path=' + s.path + '; HttpOnly'; + cookiestr = escape(s.session_key) + '='; + s.timeout = 0; } } else { - cookiestr = escape(s.session_key) + '=' - + escape(exports.serialize(s.secret, req.session)) - + '; expires=' + exports.expires(s.timeout) - + '; path=' + s.path + '; HttpOnly'; + cookiestr = escape(s.session_key) + '=' + escape(exports.serialize(s.secret, req.session)); } + if (s.useExpires) cookiestr += '; expires=' + exports.expires(s.timeout * 1000); // In milliseconds + if (s.useMaxAge) cookiestr += '; max-age=' + s.timeout; // In seconds + if (s.path) cookiestr += '; path=' + s.path; + if (s.domain) cookiestr += '; domain=' + s.domain; + if (s.secure) cookiestr += '; secure'; + if (s.useHttpOnly) cookiestr += '; HttpOnly'; + if (cookiestr !== undefined) { - if(Array.isArray(headers)) { + if(Array.isArray(headers)) { headers.push(['Set-Cookie', cookiestr]); } else { // if a Set-Cookie header already exists, convert headers to From cd8bd61bd09e484c7d2756a67036e2a4a5d148ec Mon Sep 17 00:00:00 2001 From: Public Keating Date: Fri, 13 May 2011 10:51:27 -0600 Subject: [PATCH 3/9] Don't set cookieStr parameters if it doesn't already exist --- lib/cookie-sessions.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/cookie-sessions.js b/lib/cookie-sessions.js index e53f894..59159b4 100644 --- a/lib/cookie-sessions.js +++ b/lib/cookie-sessions.js @@ -73,14 +73,14 @@ exports = module.exports = function(settings){ cookiestr = escape(s.session_key) + '=' + escape(exports.serialize(s.secret, req.session)); } - if (s.useExpires) cookiestr += '; expires=' + exports.expires(s.timeout * 1000); // In milliseconds - if (s.useMaxAge) cookiestr += '; max-age=' + s.timeout; // In seconds - if (s.path) cookiestr += '; path=' + s.path; - if (s.domain) cookiestr += '; domain=' + s.domain; - if (s.secure) cookiestr += '; secure'; - if (s.useHttpOnly) cookiestr += '; HttpOnly'; - if (cookiestr !== undefined) { + if (s.useExpires) cookiestr += '; expires=' + exports.expires(s.timeout * 1000); // In milliseconds + if (s.useMaxAge) cookiestr += '; max-age=' + s.timeout; // In seconds + if (s.path) cookiestr += '; path=' + s.path; + if (s.domain) cookiestr += '; domain=' + s.domain; + if (s.secure) cookiestr += '; secure'; + if (s.useHttpOnly) cookiestr += '; HttpOnly'; + if(Array.isArray(headers)) { headers.push(['Set-Cookie', cookiestr]); } else { From 41390b865d7752f1072e3b86ba4632aff520b709 Mon Sep 17 00:00:00 2001 From: Public Keating Date: Fri, 13 May 2011 10:53:16 -0600 Subject: [PATCH 4/9] nodeunit says .testrunner is deprecated, use .reporters.default instead --- test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.js b/test.js index f41d154..95752f4 100755 --- a/test.js +++ b/test.js @@ -5,7 +5,7 @@ require.paths.push(__dirname + '/deps'); require.paths.push(__dirname + '/lib'); try { - var testrunner = require('nodeunit').testrunner; + var testrunner = require('nodeunit').reporters.default; } catch(e) { var sys = require('sys'); From f7159f66bc0545a0b6d1a3e26e8b75ddead4ba1f Mon Sep 17 00:00:00 2001 From: Public Keating Date: Fri, 13 May 2011 10:56:38 -0600 Subject: [PATCH 5/9] Added unit tests for the new functionality --- test/test-cookie-sessions.js | 131 +++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/test/test-cookie-sessions.js b/test/test-cookie-sessions.js index c43dc87..d3595de 100644 --- a/test/test-cookie-sessions.js +++ b/test/test-cookie-sessions.js @@ -357,6 +357,7 @@ exports['writeHead'] = function(test){ headers['Set-Cookie'], '_node=serialized_session; ' + 'expires=expiry_date; ' + + 'max-age=86400; ' + 'path=/; HttpOnly' ); test.equals(headers['original'], 'header'); @@ -428,6 +429,7 @@ exports['writeHead writes empty cookie with immediate expiration if session is u headers['Set-Cookie'], '_node=; ' + 'expires=now; ' + + 'max-age=0; ' + 'path=/; HttpOnly' ); test.equals(headers['original'], 'header'); @@ -500,6 +502,7 @@ exports['set multiple cookies'] = function(test){ ['Set-Cookie', 'testcookie=testvalue'], ['Set-Cookie', '_node=session_data; ' + 'expires=expiry_date; ' + + 'max-age=12345; ' + 'path=/; HttpOnly'] ]); sessions.serialize = _serialize; @@ -536,6 +539,7 @@ exports['set single cookie'] = function(test){ 'other_header': 'val', 'Set-Cookie': '_node=session_data; ' + 'expires=expiry_date; ' + + 'max-age=12345; ' + 'path=/; HttpOnly' }); sessions.serialize = _serialize; @@ -569,6 +573,7 @@ exports['handle headers as array'] = function(test){ ['header2', 'val2'], ['Set-Cookie', '_node=session_data; ' + 'expires=expiry_date; ' + + 'max-age=12345; ' + 'path=/; HttpOnly'] ]); sessions.serialize = _serialize; @@ -664,3 +669,129 @@ exports['don\'t set cookie if incorrect path'] = function (test) { res.writeHead(200, {'other_header': 'val'}); }); }; + +exports['custom domain'] = function (test) { + test.expect(2); + var req = {headers: {cookie:''}, url: '/'}; + var res = { + writeHead: function (code, headers) { + test.equal(code, 200); + test.ok(/domain=testdomain.com/.test(headers['Set-Cookie'])); + test.done(); + } + }; + sessions({ + secret: 'secret', + domain: 'testdomain.com' + })(req, res, function () { + req.session = {test: 'test'}; + res.writeHead(200, {'other_header': 'val'}); + }); +}; + +exports['secure'] = function (test) { + test.expect(2); + var req = {headers: {cookie:''}, url: '/'}; + var res = { + writeHead: function (code, headers) { + test.equal(code, 200); + test.ok(/secure;/.test(headers['Set-Cookie'])); + test.done(); + } + }; + sessions({ + secret: 'secret', + secure: true + })(req, res, function () { + req.session = {test: 'test'}; + res.writeHead(200, {'other_header': 'val'}); + }); +}; + +exports['useExpires: false'] = function(test){ + test.expect(2); + var _serialize = sessions.serialize; + sessions.serialize = function(){ + return 'session_data'; + }; + + var req = {headers: {cookie:''}, url: '/'}; + var res = {writeHead: function(statusCode, headers){ + test.equals(statusCode, 200); + test.same(headers, { + 'other_header': 'val', + 'Set-Cookie': '_node=session_data; ' + + 'max-age=12345; ' + + 'path=/; HttpOnly' + }); + sessions.serialize = _serialize; + test.done(); + }}; + sessions({secret: 'secret', timeout: 12345, useExpires: false})(req, res, function(){ + req.session = {test: 'test'}; + res.writeHead(200, {'other_header': 'val'}); + }); +}; + +exports['useMaxAge: false'] = function(test){ + test.expect(3); + var _serialize = sessions.serialize; + sessions.serialize = function(){ + return 'session_data'; + }; + + var _expires = sessions.expires; + sessions.expires = function(timeout){ + test.equals(timeout, 12345); + return 'expiry_date'; + }; + var req = {headers: {cookie:''}, url: '/'}; + var res = {writeHead: function(statusCode, headers){ + test.equals(statusCode, 200); + test.same(headers, { + 'other_header': 'val', + 'Set-Cookie': '_node=session_data; ' + + 'expires=expiry_date; ' + + 'path=/; HttpOnly' + }); + sessions.serialize = _serialize; + sessions.expires = _expires; + test.done(); + }}; + sessions({secret: 'secret', timeout: 12345, useMaxAge: false})(req, res, function(){ + req.session = {test: 'test'}; + res.writeHead(200, {'other_header': 'val'}); + }); +}; + +exports['useHttpOnly: false'] = function(test){ + test.expect(3); + var _serialize = sessions.serialize; + sessions.serialize = function(){ + return 'session_data'; + }; + + var _expires = sessions.expires; + sessions.expires = function(timeout){ + test.equals(timeout, 12345); + return 'expiry_date'; + }; + var req = {headers: {cookie:''}, url: '/'}; + var res = {writeHead: function(statusCode, headers){ + test.equals(statusCode, 200); + test.same(headers, { + 'other_header': 'val', + 'Set-Cookie': '_node=session_data; ' + + 'expires=expiry_date; ' + + 'max-age=12345; ' + + 'path=/' + }); + sessions.serialize = _serialize; + sessions.expires = _expires; + test.done(); + }}; + sessions({secret: 'secret', timeout: 12345, useHttpOnly: false})(req, res, function(){ + req.session = {test: 'test'}; + res.writeHead(200, {'other_header': 'val'}); + }); +}; \ No newline at end of file From 43f9509979f1e41d2d071609e0eff7a97b3d0094 Mon Sep 17 00:00:00 2001 From: Public Keating Date: Fri, 13 May 2011 10:59:32 -0600 Subject: [PATCH 6/9] Let the expires() function change timeout into milliseconds, which makes it work with existing unit tests and probably a little more semantically correct. --- lib/cookie-sessions.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/cookie-sessions.js b/lib/cookie-sessions.js index 59159b4..3380d7a 100644 --- a/lib/cookie-sessions.js +++ b/lib/cookie-sessions.js @@ -74,7 +74,7 @@ exports = module.exports = function(settings){ } if (cookiestr !== undefined) { - if (s.useExpires) cookiestr += '; expires=' + exports.expires(s.timeout * 1000); // In milliseconds + if (s.useExpires) cookiestr += '; expires=' + exports.expires(s.timeout); if (s.useMaxAge) cookiestr += '; max-age=' + s.timeout; // In seconds if (s.path) cookiestr += '; path=' + s.path; if (s.domain) cookiestr += '; domain=' + s.domain; @@ -223,7 +223,8 @@ exports.readSession = function(key, secret, timeout, req){ return undefined; }; - +// Generates an expires date +// @params timeout the time in seconds before the cookie expires exports.expires = function(timeout){ - return new Date(new Date().getTime() + (timeout)).toUTCString(); + return new Date(new Date().getTime() + (timeout * 1000)).toUTCString(); }; From f2782705b2f94ee11a2df72c4d8237cd60673fbd Mon Sep 17 00:00:00 2001 From: Public Keating Date: Sat, 14 May 2011 20:03:51 -0600 Subject: [PATCH 7/9] Adjust timestamp (which is in seconds) into milliseconds for comparison with Date. --- lib/cookie-sessions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cookie-sessions.js b/lib/cookie-sessions.js index 3380d7a..7aa19c7 100644 --- a/lib/cookie-sessions.js +++ b/lib/cookie-sessions.js @@ -170,7 +170,7 @@ exports.valid = function(secret, timeout, str){ ); return ( parts.hmac_signature === hmac_sig && - parts.timestamp + timeout > new Date().getTime() + parts.timestamp + (timeout * 1000) > new Date().getTime() ); }; From 02f081f088b66091be924fde8e3646a3d84d4ded Mon Sep 17 00:00:00 2001 From: Public Keating Date: Thu, 19 May 2011 11:17:21 -0600 Subject: [PATCH 8/9] Don't mess with success! Switched back to expecting timeout to be in milliseconds, not in seconds. --- lib/cookie-sessions.js | 10 ++++----- test/test-cookie-sessions.js | 40 ++++++++++++++++++------------------ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/lib/cookie-sessions.js b/lib/cookie-sessions.js index 7aa19c7..bc16cb4 100644 --- a/lib/cookie-sessions.js +++ b/lib/cookie-sessions.js @@ -19,7 +19,7 @@ exports = module.exports = function(settings){ var default_settings = { // don't set a default cookie secret, must be explicitly defined session_key: '_node', - timeout: 60 * 60 * 24, // 24 hours in seconds + timeout: 60 * 60 * 24 * 1000, // 24 hours in milliseconds path: '/', domain: null, secure: false, @@ -75,7 +75,7 @@ exports = module.exports = function(settings){ if (cookiestr !== undefined) { if (s.useExpires) cookiestr += '; expires=' + exports.expires(s.timeout); - if (s.useMaxAge) cookiestr += '; max-age=' + s.timeout; // In seconds + if (s.useMaxAge) cookiestr += '; max-age=' + (s.timeout / 1000); // In seconds if (s.path) cookiestr += '; path=' + s.path; if (s.domain) cookiestr += '; domain=' + s.domain; if (s.secure) cookiestr += '; secure'; @@ -170,7 +170,7 @@ exports.valid = function(secret, timeout, str){ ); return ( parts.hmac_signature === hmac_sig && - parts.timestamp + (timeout * 1000) > new Date().getTime() + parts.timestamp + timeout > new Date().getTime() ); }; @@ -224,7 +224,7 @@ exports.readSession = function(key, secret, timeout, req){ }; // Generates an expires date -// @params timeout the time in seconds before the cookie expires +// @params timeout the time in milliseconds before the cookie expires exports.expires = function(timeout){ - return new Date(new Date().getTime() + (timeout * 1000)).toUTCString(); + return new Date(new Date().getTime() + timeout).toUTCString(); }; diff --git a/test/test-cookie-sessions.js b/test/test-cookie-sessions.js index d3595de..f93dcde 100644 --- a/test/test-cookie-sessions.js +++ b/test/test-cookie-sessions.js @@ -319,14 +319,14 @@ exports['onRequest'] = function(test){ var s = { session_key:'_node', secret: 'secret', - timeout: 86400 + timeout: 86400000 }; var req = {url: '/'}; sessions.readSession = function(key, secret, timeout, req){ test.equals(key, '_node', 'readSession called with session key'); test.equals(secret, 'secret', 'readSession called with secret'); - test.equals(timeout, 86400, 'readSession called with timeout'); + test.equals(timeout, 86400000, 'readSession called with timeout'); return 'testsession'; }; var next = function(){ @@ -348,7 +348,7 @@ exports['writeHead'] = function(test){ var s = { session_key:'_node', secret: 'secret', - timeout: 86400 + timeout: 86400000 }; var req = {headers: {cookie: "_node="}, url: '/'}; var res = { @@ -395,7 +395,7 @@ exports['writeHead doesnt write cookie if none exists and session is undefined'] var s = { session_key:'_node', secret: 'secret', - timeout: 86400 + timeout: 86400000 }; var req = {headers: {}, url: '/'}; var res = { @@ -420,7 +420,7 @@ exports['writeHead writes empty cookie with immediate expiration if session is u var s = { session_key:'_node', secret: 'secret', - timeout: 86400 + timeout: 86400000 }; var req = {headers: {cookie: "_node=Blah"}, url: '/'}; var res = { @@ -490,7 +490,7 @@ exports['set multiple cookies'] = function(test){ var _expires = sessions.expires; sessions.expires = function(timeout){ - test.equals(timeout, 12345); + test.equals(timeout, 12345000); return 'expiry_date'; }; @@ -510,7 +510,7 @@ exports['set multiple cookies'] = function(test){ test.done(); }}; - sessions({secret: 'secret', timeout: 12345})(req, res, function(){ + sessions({secret: 'secret', timeout: 12345000})(req, res, function(){ req.session = {test: 'test'}; res.writeHead(200, { 'other_header': 'val', @@ -528,7 +528,7 @@ exports['set single cookie'] = function(test){ var _expires = sessions.expires; sessions.expires = function(timeout){ - test.equals(timeout, 12345); + test.equals(timeout, 12345000); return 'expiry_date'; }; @@ -546,7 +546,7 @@ exports['set single cookie'] = function(test){ sessions.expires = _expires; test.done(); }}; - sessions({secret: 'secret', timeout: 12345})(req, res, function(){ + sessions({secret: 'secret', timeout: 12345000})(req, res, function(){ req.session = {test: 'test'}; res.writeHead(200, {'other_header': 'val'}); }); @@ -561,7 +561,7 @@ exports['handle headers as array'] = function(test){ var _expires = sessions.expires; sessions.expires = function(timeout){ - test.equals(timeout, 12345); + test.equals(timeout, 12345000); return 'expiry_date'; }; @@ -579,7 +579,7 @@ exports['handle headers as array'] = function(test){ sessions.serialize = _serialize; test.done(); }}; - sessions({secret: 'secret', timeout: 12345})(req, res, function(){ + sessions({secret: 'secret', timeout: 12345000})(req, res, function(){ req.session = {test: 'test'}; res.writeHead(200, [['header1', 'val1'],['header2', 'val2']]); }); @@ -607,7 +607,7 @@ exports['send cookies even if there are no headers'] = function (test) { test.done(); } }; - sessions({secret: 'secret', timeout: 12345})(req, res, function () { + sessions({secret: 'secret', timeout: 12345000})(req, res, function () { req.session = {test: 'test'}; res.writeHead(200); }); @@ -624,7 +624,7 @@ exports['send cookies when no headers but reason_phrase'] = function (test) { test.done(); } }; - sessions({secret: 'secret', timeout: 12345})(req, res, function () { + sessions({secret: 'secret', timeout: 12345000})(req, res, function () { req.session = {test: 'test'}; res.writeHead(200, 'reason'); }); @@ -642,7 +642,7 @@ exports['custom path'] = function (test) { }; sessions({ secret: 'secret', - timeout: 12345, + timeout: 12345000, path: '/test/path' })(req, res, function () { req.session = {test: 'test'}; @@ -662,7 +662,7 @@ exports['don\'t set cookie if incorrect path'] = function (test) { }; sessions({ secret: 'secret', - timeout: 12345, + timeout: 12345000, path: '/test/path' })(req, res, function () { req.session = {test: 'test'}; @@ -727,7 +727,7 @@ exports['useExpires: false'] = function(test){ sessions.serialize = _serialize; test.done(); }}; - sessions({secret: 'secret', timeout: 12345, useExpires: false})(req, res, function(){ + sessions({secret: 'secret', timeout: 12345000, useExpires: false})(req, res, function(){ req.session = {test: 'test'}; res.writeHead(200, {'other_header': 'val'}); }); @@ -742,7 +742,7 @@ exports['useMaxAge: false'] = function(test){ var _expires = sessions.expires; sessions.expires = function(timeout){ - test.equals(timeout, 12345); + test.equals(timeout, 12345000); return 'expiry_date'; }; var req = {headers: {cookie:''}, url: '/'}; @@ -758,7 +758,7 @@ exports['useMaxAge: false'] = function(test){ sessions.expires = _expires; test.done(); }}; - sessions({secret: 'secret', timeout: 12345, useMaxAge: false})(req, res, function(){ + sessions({secret: 'secret', timeout: 12345000, useMaxAge: false})(req, res, function(){ req.session = {test: 'test'}; res.writeHead(200, {'other_header': 'val'}); }); @@ -773,7 +773,7 @@ exports['useHttpOnly: false'] = function(test){ var _expires = sessions.expires; sessions.expires = function(timeout){ - test.equals(timeout, 12345); + test.equals(timeout, 12345000); return 'expiry_date'; }; var req = {headers: {cookie:''}, url: '/'}; @@ -790,7 +790,7 @@ exports['useHttpOnly: false'] = function(test){ sessions.expires = _expires; test.done(); }}; - sessions({secret: 'secret', timeout: 12345, useHttpOnly: false})(req, res, function(){ + sessions({secret: 'secret', timeout: 12345000, useHttpOnly: false})(req, res, function(){ req.session = {test: 'test'}; res.writeHead(200, {'other_header': 'val'}); }); From 8c11acc55d0a1934a14be4813923217041d3eb07 Mon Sep 17 00:00:00 2001 From: Public Keating Date: Sun, 29 May 2011 18:33:16 -0600 Subject: [PATCH 9/9] Whitespace --- lib/cookie-sessions.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/cookie-sessions.js b/lib/cookie-sessions.js index bc16cb4..ce358bd 100644 --- a/lib/cookie-sessions.js +++ b/lib/cookie-sessions.js @@ -121,7 +121,7 @@ exports.deserialize = function(secret, timeout, str){ // Parses a secure cookie string, returning the object stored within it. // Throws an exception if the secure cookie string does not validate. - if(!exports.valid(secret, timeout, str)){ + if(!exports.valid(secret, timeout, str)) { throw new Error('invalid cookie'); } var data = exports.decrypt(secret, exports.split(str).data_blob); @@ -168,6 +168,7 @@ exports.valid = function(secret, timeout, str){ var hmac_sig = exports.hmac_signature( secret, parts.timestamp, parts.data_blob ); + return ( parts.hmac_signature === hmac_sig && parts.timestamp + timeout > new Date().getTime()