Rename this.session to this.connection.

This commit is contained in:
Nick Martin
2013-12-04 02:10:47 -08:00
parent a3bbb6dfa1
commit 76c78645ff
8 changed files with 124 additions and 122 deletions

View File

@@ -78,14 +78,14 @@ Meteor.methods({
var result = tryAllLoginHandlers(options);
if (result !== null) {
this.setUserId(result.id);
Accounts._setLoginToken(this.session.id, result.token);
Accounts._setLoginToken(this.connection.id, result.token);
}
return result;
},
logout: function() {
var token = Accounts._getLoginToken(this.session.id);
Accounts._setLoginToken(this.session.id, null);
var token = Accounts._getLoginToken(this.connection.id);
Accounts._setLoginToken(this.connection.id, null);
if (token && this.userId)
removeLoginToken(this.userId, token);
this.setUserId(null);
@@ -143,27 +143,27 @@ Meteor.methods({
/// ACCOUNT DATA
///
// sessionId -> {session, loginToken, srpChallenge}
// connectionId -> {connection, loginToken, srpChallenge}
var accountData = {};
Accounts._getAccountData = function (sessionId, field) {
var data = accountData[sessionId];
Accounts._getAccountData = function (connectionId, field) {
var data = accountData[connectionId];
return data && data[field];
};
Accounts._setAccountData = function (sessionId, field, value) {
var data = accountData[sessionId];
Accounts._setAccountData = function (connectionId, field, value) {
var data = accountData[connectionId];
if (data === undefined)
delete data[field];
else
data[field] = value;
};
Meteor.server.onConnection(function (session) {
accountData[session.id] = {session: session};
session.onClose(function () {
removeSessionFromToken(session.id);
delete accountData[session.id];
Meteor.server.onConnection(function (connection) {
accountData[connection.id] = {connection: connection};
connection.onClose(function () {
removeConnectionFromToken(connection.id);
delete accountData[connection.id];
});
});
@@ -173,52 +173,52 @@ Meteor.server.onConnection(function (session) {
///
/// support reconnecting using a meteor login token
// token -> list of session ids
var sessionsByLoginToken = {};
// token -> list of connection ids
var connectionsByLoginToken = {};
// test hook
Accounts._getTokenSessions = function (token) {
return sessionsByLoginToken[token];
Accounts._getTokenConnections = function (token) {
return connectionsByLoginToken[token];
};
// Remove the session from the list of open sessions for the token.
var removeSessionFromToken = function (sessionId) {
var token = Accounts._getLoginToken(sessionId);
// Remove the connection from the list of open connections for the token.
var removeConnectionFromToken = function (connectionId) {
var token = Accounts._getLoginToken(connectionId);
if (token) {
sessionsByLoginToken[token] = _.without(
sessionsByLoginToken[token],
sessionId
connectionsByLoginToken[token] = _.without(
connectionsByLoginToken[token],
connectionId
);
if (_.isEmpty(sessionsByLoginToken[token]))
delete sessionsByLoginToken[token];
if (_.isEmpty(connectionsByLoginToken[token]))
delete connectionsByLoginToken[token];
}
};
Accounts._getLoginToken = function (sessionId) {
return Accounts._getAccountData(sessionId, 'loginToken');
Accounts._getLoginToken = function (connectionId) {
return Accounts._getAccountData(connectionId, 'loginToken');
};
Accounts._setLoginToken = function (sessionId, newToken) {
removeSessionFromToken(sessionId);
Accounts._setLoginToken = function (connectionId, newToken) {
removeConnectionFromToken(connectionId);
Accounts._setAccountData(sessionId, 'loginToken', newToken);
Accounts._setAccountData(connectionId, 'loginToken', newToken);
if (newToken) {
if (! _.has(sessionsByLoginToken, newToken))
sessionsByLoginToken[newToken] = [];
sessionsByLoginToken[newToken].push(sessionId);
if (! _.has(connectionsByLoginToken, newToken))
connectionsByLoginToken[newToken] = [];
connectionsByLoginToken[newToken].push(connectionId);
}
};
// Close all open sessions associated with any of the tokens in
// Close all open connections associated with any of the tokens in
// `tokens`.
var closeSessionsForTokens = function (tokens) {
var closeConnectionsForTokens = function (tokens) {
_.each(tokens, function (token) {
if (_.has(sessionsByLoginToken, token)) {
_.each(sessionsByLoginToken[token], function (sessionId) {
var session = Accounts._getAccountData(sessionId, 'session');
if (session)
session.close();
if (_.has(connectionsByLoginToken, token)) {
_.each(connectionsByLoginToken[token], function (connectionId) {
var connection = Accounts._getAccountData(connectionId, 'connection');
if (connection)
connection.close();
});
}
});
@@ -727,7 +727,7 @@ Meteor.startup(function () {
///
var closeTokensForUser = function (userTokens) {
closeSessionsForTokens(_.pluck(userTokens, "token"));
closeConnectionsForTokens(_.pluck(userTokens, "token"));
};
// Like _.difference, but uses EJSON.equals to compute which values to return.

View File

@@ -211,20 +211,20 @@ Tinytest.addAsync('accounts - expire numeric token', function (test, onComplete)
Tinytest.addAsync(
'accounts - session data cleaned up',
'accounts - connection data cleaned up',
function (test, onComplete) {
makeTestConnection(
test,
function (connection, session) {
function (clientConn, serverConn) {
// onClose callbacks are called in order, so we run after the
// close callback in accounts.
session.onClose(function () {
test.isFalse(Accounts._getAccountData(session.id, 'session'));
serverConn.onClose(function () {
test.isFalse(Accounts._getAccountData(serverConn.id, 'connection'));
onComplete();
});
test.isTrue(Accounts._getAccountData(session.id, 'session'));
session.close();
test.isTrue(Accounts._getAccountData(serverConn.id, 'connection'));
serverConn.close();
},
onComplete
);

View File

@@ -66,7 +66,7 @@ Meteor.methods({beginPasswordExchange: function (request) {
var challenge = srp.issueChallenge({A: request.A});
// Save results so we can verify them later.
Accounts._setAccountData(this.session.id, 'srpChallenge',
Accounts._setAccountData(this.connection.id, 'srpChallenge',
{ userId: user._id, M: srp.M, HAMK: srp.HAMK }
);
return challenge;
@@ -82,11 +82,11 @@ Accounts.registerLoginHandler(function (options) {
// we're always called from within a 'login' method, so this should
// be safe.
var currentInvocation = DDP._CurrentInvocation.get();
var serialized = Accounts._getAccountData(currentInvocation.session.id, 'srpChallenge');
var serialized = Accounts._getAccountData(currentInvocation.connection.id, 'srpChallenge');
if (!serialized || serialized.M !== options.srp.M)
throw new Meteor.Error(403, "Incorrect password");
// Only can use challenges once.
Accounts._setAccountData(currentInvocation.session.id, 'srpChallenge', undefined);
Accounts._setAccountData(currentInvocation.connection.id, 'srpChallenge', undefined);
var userId = serialized.userId;
var user = Meteor.users.findOne(userId);
@@ -167,14 +167,14 @@ Meteor.methods({changePassword: function (options) {
password: Match.Optional(String)
});
var serialized = Accounts._getAccountData(this.session.id, 'srpChallenge');
var serialized = Accounts._getAccountData(this.connection.id, 'srpChallenge');
if (!serialized || serialized.M !== options.M)
throw new Meteor.Error(403, "Incorrect password");
if (serialized.userId !== this.userId)
// No monkey business!
throw new Meteor.Error(403, "Incorrect password");
// Only can use challenges once.
Accounts._setAccountData(this.session.id, 'srpChallenge', undefined);
Accounts._setAccountData(this.connection.id, 'srpChallenge', undefined);
var verifier = options.srp;
if (!verifier && options.password) {
@@ -319,8 +319,8 @@ Meteor.methods({resetPassword: function (token, newVerifier) {
// logged in as. Make sure to avoid logging ourselves out if this
// happens. But also make sure not to leave the connection in a state
// of having a bad token set if things fail.
var oldToken = Accounts._getLoginToken(this.session.id);
Accounts._setLoginToken(this.session.id, null);
var oldToken = Accounts._getLoginToken(this.connection.id);
Accounts._setLoginToken(this.connection.id, null);
try {
// Update the user record by:
@@ -337,11 +337,11 @@ Meteor.methods({resetPassword: function (token, newVerifier) {
});
} catch (err) {
// update failed somehow. reset to old token.
Accounts._setLoginToken(this.session.id, oldToken);
Accounts._setLoginToken(this.connection.id, oldToken);
throw err;
}
Accounts._setLoginToken(this.session.id, stampedLoginToken.token);
Accounts._setLoginToken(this.connection.id, stampedLoginToken.token);
this.setUserId(user._id);
return {
@@ -435,7 +435,7 @@ Meteor.methods({verifyEmail: function (token) {
$push: {'services.resume.loginTokens': stampedLoginToken}});
this.setUserId(user._id);
Accounts._setLoginToken(this.session.id, stampedLoginToken.token);
Accounts._setLoginToken(this.connection.id, stampedLoginToken.token);
return {
token: stampedLoginToken.token,
tokenExpires: Accounts._tokenExpiration(stampedLoginToken.when),
@@ -514,7 +514,7 @@ Meteor.methods({createUser: function (options) {
// client gets logged in as the new user afterwards.
this.setUserId(result.id);
Accounts._setLoginToken(this.session.id, result.token);
Accounts._setLoginToken(this.connection.id, result.token);
return result;
}});

View File

@@ -555,21 +555,23 @@ if (Meteor.isServer) (function () {
makeTestConnection(
test,
function (connection, session) {
session.onClose(function () {
test.isFalse(_.contains(Accounts._getTokenSessions(token), session.id));
function (clientConn, serverConn) {
serverConn.onClose(function () {
test.isFalse(_.contains(
Accounts._getTokenConnections(token), serverConn.id));
onComplete();
});
var result = connection.call('login', {
var result = clientConn.call('login', {
user: {username: username},
password: 'password'
});
test.isTrue(result);
var token = Accounts._getAccountData(session.id, 'loginToken');
var token = Accounts._getAccountData(serverConn.id, 'loginToken');
test.isTrue(token);
test.equal(result.token, token);
test.isTrue(_.contains(Accounts._getTokenSessions(token), session.id));
connection.disconnect();
test.isTrue(_.contains(
Accounts._getTokenConnections(token), serverConn.id));
clientConn.disconnect();
},
onComplete
);

View File

@@ -29,8 +29,8 @@ MethodInvocation = function (options) {
// reruns subscriptions
this._setUserId = options.setUserId || function () {};
// On the server, the session this method call came in on.
this.session = options.session;
// On the server, the connection this method call came in on.
this.connection = options.connection;
};
_.extend(MethodInvocation.prototype, {

View File

@@ -247,19 +247,19 @@ var Session = function (server, version, socket) {
// we want to buffer up for when we are done rerunning subscriptions
self._pendingReady = [];
// List of callbacks to call when this session is closed.
// List of callbacks to call when this connection is closed.
self._closeCallbacks = [];
// The `SessionHandle` for this session, passed to
// The `ConnectionHandle` for this session, passed to
// `Meteor.server.onConnection` callbacks.
self.sessionHandle = {
self.connectionHandle = {
id: self.id,
close: function () {
self.server._closeSession(self);
},
onClose: function (fn) {
self._closeCallbacks.push(
Meteor.bindEnvironment(fn, "connection session onClose callback")
Meteor.bindEnvironment(fn, "connection onClose callback")
);
}
};
@@ -554,7 +554,7 @@ _.extend(Session.prototype, {
userId: self.userId,
setUserId: setUserId,
unblock: unblock,
session: self.sessionHandle
connection: self.connectionHandle
});
try {
var result = DDPServer._CurrentWriteFence.withValue(fence, function () {
@@ -728,7 +728,7 @@ var Subscription = function (
session, handler, subscriptionId, params, name) {
var self = this;
self._session = session; // type is Session
self.session = session.sessionHandle; // public API object
self.connection = session.connectionHandle; // public API object
self._handler = handler;
@@ -1087,7 +1087,7 @@ _.extend(Server.prototype, {
self.sessions[socket._meteorSession.id] = socket._meteorSession;
_.each(self.connectionCallbacks, function (callback) {
if (socket._meteorSession)
callback(socket._meteorSession.sessionHandle);
callback(socket._meteorSession.connectionHandle);
});
} else if (!msg.version) {
// connect message without a version. This means an old (pre-pre1)
@@ -1244,21 +1244,21 @@ _.extend(Server.prototype, {
var setUserId = function() {
throw new Error("Can't call setUserId on a server initiated method call");
};
var session = null;
var connection = null;
var currentInvocation = DDP._CurrentInvocation.get();
if (currentInvocation) {
userId = currentInvocation.userId;
setUserId = function(userId) {
currentInvocation.setUserId(userId);
};
session = currentInvocation.session;
connection = currentInvocation.connection;
}
var invocation = new MethodInvocation({
isSimulation: false,
userId: userId,
setUserId: setUserId,
session: session
connection: connection
});
try {
var result = DDP._CurrentInvocation.withValue(invocation, function () {

View File

@@ -2,17 +2,17 @@ var Fiber = Npm.require('fibers');
Tinytest.addAsync(
"livedata server - sessionHandle.onClose()",
"livedata server - connectionHandle.onClose()",
function (test, onComplete) {
makeTestConnection(
test,
function (connection, session) {
function (clientConn, serverConn) {
// On the server side, wait for the connection to be closed.
session.onClose(function () {
serverConn.onClose(function () {
onComplete();
});
// Close the connection from the client.
connection.disconnect();
clientConn.disconnect();
},
onComplete
);
@@ -21,15 +21,15 @@ Tinytest.addAsync(
Tinytest.addAsync(
"livedata server - sessionHandle.close()",
"livedata server - connectionHandle.close()",
function (test, onComplete) {
makeTestConnection(
test,
function (connection, session) {
function (clientConn, serverConn) {
// Wait for the connection to be closed from the server side.
simplePoll(
function () {
return ! connection.status().connected;
return ! clientConn.status().connected;
},
onComplete,
function () {
@@ -39,7 +39,7 @@ Tinytest.addAsync(
);
// Close the connection from the server.
session.close();
serverConn.close();
},
onComplete
);
@@ -49,7 +49,7 @@ Tinytest.addAsync(
Meteor.methods({
livedata_server_test_inner: function () {
return this.session.id;
return this.connection.id;
},
livedata_server_test_outer: function () {
@@ -59,14 +59,14 @@ Meteor.methods({
Tinytest.addAsync(
"livedata server - session in method invocation",
"livedata server - connection in method invocation",
function (test, onComplete) {
makeTestConnection(
test,
function (connection, session) {
var res = connection.call('livedata_server_test_inner');
test.equal(res, session.id);
connection.disconnect();
function (clientConn, serverConn) {
var res = clientConn.call('livedata_server_test_inner');
test.equal(res, serverConn.id);
clientConn.disconnect();
onComplete();
},
onComplete
@@ -76,14 +76,14 @@ Tinytest.addAsync(
Tinytest.addAsync(
"livedata server - session in nested method invocation",
"livedata server - connection in nested method invocation",
function (test, onComplete) {
makeTestConnection(
test,
function (connection, session) {
var res = connection.call('livedata_server_test_outer');
test.equal(res, session.id);
connection.disconnect();
function (clientConn, serverConn) {
var res = clientConn.call('livedata_server_test_outer');
test.equal(res, serverConn.id);
clientConn.disconnect();
onComplete();
},
onComplete
@@ -92,11 +92,11 @@ Tinytest.addAsync(
);
// sessionId -> callback
// connectionId -> callback
var onSubscription = {};
Meteor.publish("livedata_server_test_sub", function (sessionId) {
var callback = onSubscription[sessionId];
Meteor.publish("livedata_server_test_sub", function (connectionId) {
var callback = onSubscription[connectionId];
if (callback)
callback(this);
this.stop();
@@ -104,18 +104,18 @@ Meteor.publish("livedata_server_test_sub", function (sessionId) {
Tinytest.addAsync(
"livedata server - session in publish function",
"livedata server - connection in publish function",
function (test, onComplete) {
makeTestConnection(
test,
function (connection, session) {
onSubscription[session.id] = function (subscription) {
delete onSubscription[session.id];
test.equal(subscription.session.id, session.id);
connection.disconnect();
function (clientConn, serverConn) {
onSubscription[serverConn.id] = function (subscription) {
delete onSubscription[serverConn.id];
test.equal(subscription.connection.id, serverConn.id);
clientConn.disconnect();
onComplete();
};
connection.subscribe("livedata_server_test_sub", session.id);
clientConn.subscribe("livedata_server_test_sub", serverConn.id);
}
);
}

View File

@@ -1,52 +1,52 @@
// Establish a connection from the server to the server, and wait
// until the client side of the connection has received the session
// id. On success call `succeeded` with two arguments, the client
// side `connection` and the server side `session`. Call `failed` on
// side connection and the server side connection handle. Call `failed` on
// failure.
makeTestConnection = function (test, succeeded, failed) {
// The connection from the client side.
var connection;
var clientConn;
// Track incoming sessions server side until we know which one is
// Track incoming connections server side until we know which one is
// ours.
var sessions = {};
var serverConns = {};
// Add incoming sessions to `sessions`.
var onConnectionHandle = Meteor.onConnection(function (session) {
test.isTrue(_.isString(session.id), "session handle id exists and is a string");
if (sessions[session.id]) {
// Add incoming connections to `serverConns`.
var onConnectionHandle = Meteor.onConnection(function (serverConn) {
test.isTrue(_.isString(serverConn.id), "connection handle id exists and is a string");
if (serverConns[serverConn.id]) {
test.fail("onConnection callback called multiple times for same session id");
failed();
}
else {
sessions[session.id] = session;
serverConns[serverConn.id] = serverConn;
}
});
// We've succeeded when we get the session id on the client side.
var onClientSessionId = function (sessionId) {
test.isTrue(connection.status().connected);
var session = sessions[sessionId];
if (! session) {
test.isTrue(clientConn.status().connected);
var serverConn = serverConns[sessionId];
if (! serverConn) {
test.fail("No onConnection received server side for connected client");
failed();
}
else {
onConnectionHandle.stop();
succeeded(connection, session);
succeeded(clientConn, serverConn);
}
};
// Connect and wait until the connection receives its session id.
// Disable retries so that when the connection is closed we don't
// automatically keep reconnecting on the client side.
connection = DDP.connect(Meteor.absoluteUrl(), {retry: false});
clientConn = DDP.connect(Meteor.absoluteUrl(), {retry: false});
simplePoll(
function () {
return connection._lastSessionId;
return clientConn._lastSessionId;
},
function () {
onClientSessionId(connection._lastSessionId);
onClientSessionId(clientConn._lastSessionId);
},
function () {
test.fail("client side of connection did not receive a session id");