From 64a6661c51282a7b4a978cedf6be22853651f843 Mon Sep 17 00:00:00 2001 From: Dean Brettle Date: Sat, 15 Aug 2015 23:45:30 -0700 Subject: [PATCH 1/2] Fix #4970 - Login fail while logged in breaks reconnect autologin Change callLoginMethod to leave self.connection.onReconnect alone if the login fails, and add test for same. --- packages/accounts-base/accounts_client.js | 4 +- .../accounts-base/accounts_reconnect_tests.js | 74 +++++++++++++++++++ packages/accounts-base/package.js | 4 +- 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 packages/accounts-base/accounts_reconnect_tests.js diff --git a/packages/accounts-base/accounts_client.js b/packages/accounts-base/accounts_client.js index 006d26f816..0b0953447c 100644 --- a/packages/accounts-base/accounts_client.js +++ b/packages/accounts-base/accounts_client.js @@ -213,7 +213,9 @@ Ap.callLoginMethod = function (options) { // will occur before the callback from the resume login call.) var onResultReceived = function (err, result) { if (err || !result || !result.token) { - self.connection.onReconnect = null; + // Leave onReconnect alone if there was an error, so that if the user was + // already logged in they will still get logged in on reconnect. + // See issue #4970. } else { self.connection.onReconnect = function () { reconnected = true; diff --git a/packages/accounts-base/accounts_reconnect_tests.js b/packages/accounts-base/accounts_reconnect_tests.js new file mode 100644 index 0000000000..859044dbfd --- /dev/null +++ b/packages/accounts-base/accounts_reconnect_tests.js @@ -0,0 +1,74 @@ +if (Meteor.isServer) { + Meteor.methods({ + getConnectionUserId: function() { + return this.userId; + } + }); +} + +if (Meteor.isClient) { + Tinytest.addAsync('accounts - reconnect auto-login', function(test, done) { + var username1 = 'testuser1-' + Random.id(); + var username2 = 'testuser2-' + Random.id(); + var password1 = 'password1-' + Random.id(); + var password2 = 'password2-' + Random.id(); + var timeoutHandle; + var onLoginStopper; + + loginAsUser1(); + + function loginAsUser1() { + Accounts.createUser({ + username: username1, + password: password1 + }, onUser1LoggedIn); + } + + function onUser1LoggedIn(err) { + test.isUndefined(err, 'Unexpected error logging in as user1'); + Accounts.createUser({ + username: username2, + password: password2 + }, onUser2LoggedIn); + } + + function onUser2LoggedIn(err) { + test.isUndefined(err, 'Unexpected error logging in as user2'); + onLoginStopper = Accounts.onLogin(onUser2LoggedInAfterReconnect); + Meteor.disconnect(); + Meteor.reconnect(); + } + + function onUser2LoggedInAfterReconnect() { + onLoginStopper.stop(); + Meteor.loginWithPassword('non-existent-user', 'or-wrong-password', + onFailedLogin); + } + + function onFailedLogin(err) { + test.instanceOf(err, Meteor.Error, 'No Meteor.Error on login failure'); + onLoginStopper = Accounts.onLogin(onUser2LoggedInAfterReconnectAfterFailedLogin); + Meteor.disconnect(); + Meteor.reconnect(); + timeoutHandle = Meteor.setTimeout(failTest, 1000); + } + + function failTest() { + test.fail('Issue #4970 has occured.'); + Meteor.call('getConnectionUserId', checkFinalState); + } + + function onUser2LoggedInAfterReconnectAfterFailedLogin() { + onLoginStopper.stop(); + Meteor.clearTimeout(timeoutHandle); + Meteor.call('getConnectionUserId', checkFinalState); + } + + function checkFinalState(err, connectionUserId) { + test.isUndefined(err, 'Unexpected error calling getConnectionUserId'); + test.equal(connectionUserId, Meteor.userId(), + 'userId is different on client and server'); + done(); + } + }); +} diff --git a/packages/accounts-base/package.js b/packages/accounts-base/package.js index 7db9e877e8..f448932eb7 100644 --- a/packages/accounts-base/package.js +++ b/packages/accounts-base/package.js @@ -69,9 +69,11 @@ Package.onTest(function (api) { 'test-helpers', 'oauth-encryption', 'underscore', - 'ddp' + 'ddp', + 'accounts-password' ]); api.addFiles('accounts_tests.js', 'server'); api.addFiles("accounts_url_tests.js", "client"); + api.addFiles("accounts_reconnect_tests.js"); }); From 675349f988d9e7fef96dd5d89b4d38e3f0b48342 Mon Sep 17 00:00:00 2001 From: Dean Brettle Date: Sun, 16 Aug 2015 00:27:19 -0700 Subject: [PATCH 2/2] Stop onLogin handler even if test fails. --- packages/accounts-base/accounts_reconnect_tests.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/accounts-base/accounts_reconnect_tests.js b/packages/accounts-base/accounts_reconnect_tests.js index 859044dbfd..143f14bc0a 100644 --- a/packages/accounts-base/accounts_reconnect_tests.js +++ b/packages/accounts-base/accounts_reconnect_tests.js @@ -54,6 +54,7 @@ if (Meteor.isClient) { } function failTest() { + onLoginStopper.stop(); test.fail('Issue #4970 has occured.'); Meteor.call('getConnectionUserId', checkFinalState); }