Tizen 2.1 base
[platform/framework/web/web-ui-fw.git] / libs / js / jquery-mobile-1.2.0 / node_modules / grunt / node_modules / connect / lib / middleware / cookieSession.js
1
2 /*!
3  * Connect - cookieSession
4  * Copyright(c) 2011 Sencha Inc.
5  * MIT Licensed
6  */
7
8 /**
9  * Module dependencies.
10  */
11
12 var utils = require('./../utils')
13   , Cookie = require('./session/cookie')
14   , debug = require('debug')('connect:cookieSession')
15   , crc16 = require('crc').crc16;
16
17 // environment
18
19 var env = process.env.NODE_ENV;
20
21 /**
22  * Cookie Session:
23  *
24  *   Cookie session middleware.
25  *
26  *      var app = connect();
27  *      app.use(connect.cookieParser());
28  *      app.use(connect.cookieSession({ secret: 'tobo!', cookie: { maxAge: 60 * 60 * 1000 }}));
29  *
30  * Options:
31  *
32  *   - `key` cookie name defaulting to `connect.sess`
33  *   - `secret` prevents cookie tampering
34  *   - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }`
35  *   - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto")
36  *
37  * Clearing sessions:
38  *
39  *  To clear the session simply set its value to `null`,
40  *  `cookieSession()` will then respond with a 1970 Set-Cookie.
41  *
42  *     req.session = null;
43  *
44  * @param {Object} options
45  * @return {Function}
46  * @api public
47  */
48
49 module.exports = function cookieSession(options){
50   // TODO: utilize Session/Cookie to unify API
51   var options = options || {}
52     , key = options.key || 'connect.sess'
53     , trustProxy = options.proxy;
54
55   return function cookieSession(req, res, next) {
56
57     // req.secret is for backwards compatibility
58     var secret = options.secret || req.secret;
59     if (!secret) throw new Error('`secret` option required for cookie sessions');
60
61     // default session
62     req.session = {};
63     var cookie = req.session.cookie = new Cookie(options.cookie);
64
65     // pathname mismatch
66     if (0 != req.originalUrl.indexOf(cookie.path)) return next();
67
68     // cookieParser secret
69     if (!options.secret && req.secret) {
70       req.session = req.signedCookies[key] || {};
71     } else {
72       // TODO: refactor
73       var rawCookie = req.cookies[key];
74       if (rawCookie) {
75         var unsigned = utils.parseSignedCookie(rawCookie, secret);
76         if (unsigned) {
77           var originalHash = crc16(unsigned);
78           req.session = utils.parseJSONCookie(unsigned) || {};
79         }
80       }
81     }
82
83     res.on('header', function(){
84       // removed
85       if (!req.session) {
86         debug('clear session');
87         cookie.expires = new Date(0);
88         res.setHeader('Set-Cookie', cookie.serialize(key, ''));
89         return;
90       }
91
92       delete req.session.cookie;
93
94       // check security
95       var proto = (req.headers['x-forwarded-proto'] || '').toLowerCase()
96         , tls = req.connection.encrypted || (trustProxy && 'https' == proto)
97         , secured = cookie.secure && tls;
98
99       // only send secure cookies via https
100       if (cookie.secure && !secured) return debug('not secured');
101
102       // serialize
103       debug('serializing %j', req.session);
104       var val = 'j:' + JSON.stringify(req.session);
105
106       // compare hashes, no need to set-cookie if unchanged
107       if (originalHash == crc16(val)) return debug('unmodified session');
108
109       // set-cookie
110       val = 's:' + utils.sign(val, secret);
111       val = cookie.serialize(key, val);
112       debug('set-cookie %j', cookie);
113       res.setHeader('Set-Cookie', val);
114     });
115
116     next();
117   };
118 };