diff --git a/lib/cookie-sessions.js b/lib/cookie-sessions.js index bc14262..d1acec9 100644 --- a/lib/cookie-sessions.js +++ b/lib/cookie-sessions.js @@ -26,76 +26,35 @@ var exports = module.exports = function(settings){ req.session = exports.readSession( s.session_key, s.secret, s.timeout, req); - // proxy writeHead to add cookie to response - var _writeHead = res.writeHead; - res.writeHead = function(statusCode){ - - var reasonPhrase, headers; - if (typeof arguments[1] === 'string') { - reasonPhrase = arguments[1]; - headers = arguments[2] || {}; - } - else { - headers = arguments[1] || {}; - } - - // Add a Set-Cookie header to all responses with the session data - // and the current timestamp. The cookie needs to be set on every - // response so that the timestamp is up to date, and the session - // does not expire unless the user is inactive. - - var cookiestr; - if (req.session === undefined) { - if ("cookie" in req.headers) { - cookiestr = escape(s.session_key) + '=' - + '; expires=' + exports.expires(0) - + '; path=' + s.path + '; HttpOnly'; - } - } else { - cookiestr = escape(s.session_key) + '=' - + escape(exports.serialize(s.secret, req.session)) - + '; expires=' + exports.expires(s.timeout) - + '; path=' + s.path + '; HttpOnly'; - } - - if (cookiestr !== undefined) { - 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){ - 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 { - headers['Set-Cookie'] = cookiestr; - } - } - } - - var args = [statusCode, reasonPhrase, headers]; - if (!args[1]) { - args.splice(1, 1); - } - // call the original writeHead on the request - return _writeHead.apply(res, args); - } + var writeHead = res.writeHead; + res.writeHead = function(status, headers){ + // TODO: In the old version a session-cookie will be set on every request. + // It has to be checked whether this is useful or not. + if (req.session) { + res.setHeader('Set-Cookie', buildCookieStr(s, req.session)); + } + + res.writeHead = writeHead; + return res.writeHead(status, headers); + }; + + // TODO: This is from connect/session, which works fine with other SessionStores. + // It has to be checked whether this us useful in out circumstance. + var end = res.end; + res.end = function(data, encoding) { + res.end = end; + // HACK: ensure Set-Cookie for implicit writeHead() + if (req.session && !res._header) { + res._implicitHeader(); + } + res.end(data, encoding); + }; + next(); }; }; -exports.headersToArray = function(headers){ - if(Array.isArray(headers)) return headers; - return Object.keys(headers).reduce(function(arr, k){ - arr.push([k, headers[k]]); - return arr; - }, []); -}; - - // Extend a given object with all the properties in passed-in object(s). // From underscore.js (http://documentcloud.github.com/underscore/) function extend(obj) { @@ -105,6 +64,13 @@ function extend(obj) { return obj; }; +function buildCookieStr(settings, session) { + return escape(settings.session_key) + '=' + + escape(exports.serialize(settings.secret, session)) + + '; expires=' + exports.expires(settings.timeout) + + '; path=' + settings.path + '; HttpOnly'; +}; + 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. @@ -113,7 +79,10 @@ exports.deserialize = function(secret, timeout, str){ throw new Error('invalid cookie'); } var data = exports.decrypt(secret, exports.split(str).data_blob); - return JSON.parse(data); + var timestamp = exports.split(str).timestamp; + var json = JSON.parse(data); + json.timestamp = timestamp; + return json; }; exports.serialize = function(secret, data){ diff --git a/package.json b/package.json index 4b4202d..bf2b8d2 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "cookie-sessions" , "description": "Secure cookie-based session middleware for Connect" , "main": "./index" -, "author": "Caolan McMahon" +, "author": "Original Author: Caolan McMahon" , "version": "0.0.2" , "repository" : { "type" : "git" - , "url" : "http://github.com/caolan/cookie-sessions.git" + , "url" : "http://github.com/jenshimmelreich/cookie-sessions.git" } -, "bugs" : { "web" : "http://github.com/caolan/cookie-sessions/issues" } +, "bugs" : { "url" : "http://github.com/jenshimmelreich/cookie-sessions/issues" } , "licenses" : [ { "type" : "MIT" , "url" : "http://github.com/caolan/cookie-sessions/raw/master/LICENSE"