index.js
3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
var cookieparser = require('cookie-parser');
var debug = require('debug')('express-socket.io-session');
var hash = require('./lib/hash');
// The express session object will be set
// in socket.handskake.session.
/**
* Returns a middleware function that acts on socket.handshake
*
* @param {Function} expressSessionMiddleware - An express-session middleware function to reuse with io.use
* @param {Function} cookieParserMiddleware - An express-session middleware function to reuse with express-session
* @param {Object} options - An object with some options for overriding default behaviour.
* - {Boolean} autSave - If true, the session variables will be saved asyncrhonously to express-session driver
* by wrapping the method socket.on
*/
module.exports = function(
expressSessionMiddleware,
cookieParserMiddleware,
options
) {
var socketIoSharedSessionMiddleware;
// Accept options as second argument if only 2 parameters passed
if (arguments.length == 2 && typeof cookieParserMiddleware === 'object') {
options = cookieParserMiddleware;
cookieParserMiddleware = undefined;
}
if (typeof cookieParserMiddleware === 'undefined') {
debug(
'No cookie-parser instance passed as argument. Creating a cookie-parser ' +
'instance with default values'
);
cookieParserMiddleware = cookieparser();
}
options = options || {};
var saveUninitializedSession = options.saveUninitialized;
debug('Creating socket.io middleware');
socketIoSharedSessionMiddleware = function(socket, next) {
var req = socket.handshake;
var res = {
end: function() {}
};
// originalHash, savedHash, originalId, cookieId
// are variables present for replicating express-session autoSaving behaviour
var originalHash, savedHash;
var originalId;
var cookieId;
var _onevent = socket.onevent;
// Override socket.on if autoSave = true;
if (options.autoSave === true) {
debug(
'Using autoSave feature. express-session middleware will be called on every event received'
);
socket.onevent = function() {
debug(
'Executing socket.onevent monkeypatched by express-socket.io-session'
);
var _args = arguments;
originalHash = savedHash = hash(req.session);
cookieId = req.sessionID;
originalId = req.sessionID;
_onevent.apply(socket, _args);
process.nextTick(function() {
if (shouldSave(req)) {
req.session.touch();
req.session.save();
}
});
};
}
//Parse session cookie
cookieParserMiddleware(req, res, function(err) {
if (err) {
debug('cookieParser errored');
return next(err);
}
expressSessionMiddleware(req, res, function(req, res) {
next();
});
});
/*
* These functions hash, isModified, isSaved, shouldSave
* and shouldDestroy are canibalized from express-session
* in order to this module being able to comply with the autoSave options.
*/
// check if session has been modified
function isModified(sess) {
return originalId !== sess.id || originalHash !== hash(sess);
}
// check if session has been saved
function isSaved(sess) {
return originalId === sess.id && savedHash === hash(sess);
}
// determine if session should be saved to store
function shouldSave(req) {
// cannot set cookie without a session ID
if (typeof req.sessionID !== 'string') {
debug(
'session ignored because of bogus req.sessionID %o',
req.sessionID
);
return false;
}
return !saveUninitializedSession && cookieId !== req.sessionID
? isModified(req.session)
: !isSaved(req.session);
}
};
return socketIoSharedSessionMiddleware;
};