From 555e1d4415eed305590b7eb5340df572bcdd8992 Mon Sep 17 00:00:00 2001 From: Peter Mooney Date: Wed, 20 Apr 2016 23:30:36 -0400 Subject: [PATCH 1/4] Add logout hooks to accounts-base --- packages/accounts-base/accounts_client.js | 7 +++++++ packages/accounts-base/accounts_common.js | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/packages/accounts-base/accounts_client.js b/packages/accounts-base/accounts_client.js index e089b45eb1..a7e83902f5 100644 --- a/packages/accounts-base/accounts_client.js +++ b/packages/accounts-base/accounts_client.js @@ -319,6 +319,13 @@ Ap.callLoginMethod = function (options) { }; Ap.makeClientLoggedOut = function () { + // Ensure client was successfully logged in before running logout hooks. + if (this.connection._userId) { + this._onLogoutHook.each(function (callback) { + callback(); + return true; + }); + } this._unstoreLoginToken(); this.connection.setUserId(null); this.connection.onReconnect = null; diff --git a/packages/accounts-base/accounts_common.js b/packages/accounts-base/accounts_common.js index a8f49b00f8..8282789cfa 100644 --- a/packages/accounts-base/accounts_common.js +++ b/packages/accounts-base/accounts_common.js @@ -35,6 +35,11 @@ export class AccountsCommon { bindEnvironment: false, debugPrintExceptions: "onLoginFailure callback" }); + + this._onLogoutHook = new Hook({ + bindEnvironment: false, + debugPrintExceptions: "onLogout callback" + }); } /** @@ -156,6 +161,15 @@ export class AccountsCommon { return this._onLoginFailureHook.register(func); } + /** + * @summary Register a callback to be called after a logout attempt succeeds. + * @locus Anywhere + * @param {Function} func The callback to be called when logout is successful. + */ + onLogout(func) { + return this._onLogoutHook.register(func); + } + _initConnection(options) { if (! Meteor.isClient) { return; From 4eff26c6bbc9d8cb48a658d1fe4242b91ea3768e Mon Sep 17 00:00:00 2001 From: Peter Mooney Date: Sun, 24 Apr 2016 00:02:26 -0400 Subject: [PATCH 2/4] Invoke onLogout hook on server --- packages/accounts-base/accounts_server.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/accounts-base/accounts_server.js b/packages/accounts-base/accounts_server.js index 6783d1ff8b..dbffd61e64 100644 --- a/packages/accounts-base/accounts_server.js +++ b/packages/accounts-base/accounts_server.js @@ -176,6 +176,12 @@ Ap._failedLogin = function (connection, attempt) { }); }; +Ap._successfulLogout = function () { + this._onLogoutHook.each(function (callback) { + callback(); + return true; + }); +}; /// /// LOGIN METHODS @@ -532,6 +538,7 @@ Ap._initServerMethods = function () { if (token && this.userId) accounts.destroyToken(this.userId, token); this.setUserId(null); + accounts._successfulLogout(); }; // Delete all the current user's tokens and close all open connections logged From 61a0cd0c5c1593591afb547bf1641d75990aed5c Mon Sep 17 00:00:00 2001 From: Peter Mooney Date: Sun, 24 Apr 2016 12:46:49 -0400 Subject: [PATCH 3/4] Add client/server onLogout tests --- packages/accounts-password/password_tests.js | 48 +++++++++++++++++++ .../accounts-password/password_tests_setup.js | 16 +++++++ 2 files changed, 64 insertions(+) diff --git a/packages/accounts-password/password_tests.js b/packages/accounts-password/password_tests.js index 3a3628ee01..b6f831d6f6 100644 --- a/packages/accounts-password/password_tests.js +++ b/packages/accounts-password/password_tests.js @@ -996,6 +996,54 @@ if (Meteor.isClient) (function () { } ]); + testAsyncMulti("passwords - server onLogout hook", [ + function (test, expect) { + Meteor.call("testCaptureLogouts", expect(function (error) { + test.isFalse(error); + })); + }, + function (test, expect) { + this.username = Random.id(); + this.password = "password"; + + Accounts.createUser( + {username: this.username, password: this.password}, + loggedInAs(this.username, test, expect)); + }, + logoutStep, + function (test, expect) { + var self = this; + Meteor.call("testFetchCapturedLogouts", expect(function (error, logouts) { + test.isFalse(error); + test.equal(logouts.length, 1); + var logout = logouts[0]; + test.isTrue(logout.successful); + })); + } + ]); + + testAsyncMulti("passwords - client onLogout hook", [ + function (test, expect) { + var self = this; + this.username = Random.id(); + this.password = "password"; + this.attempt = false; + + this.onLogout = Accounts.onLogout(function () { + self.logoutSuccess = true; + }); + + Accounts.createUser( + {username: this.username, password: this.password}, + loggedInAs(this.username, test, expect)); + }, + logoutStep, + function (test, expect) { + test.isTrue(this.logoutSuccess); + expect(function() {})(); + } + ]); + testAsyncMulti("passwords - server onLoginFailure hook", [ function (test, expect) { this.username = Random.id(); diff --git a/packages/accounts-password/password_tests_setup.js b/packages/accounts-password/password_tests_setup.js index 9f46f7f79a..07db15556b 100644 --- a/packages/accounts-password/password_tests_setup.js +++ b/packages/accounts-password/password_tests_setup.js @@ -54,6 +54,10 @@ Meteor.methods({ capturedLogins[this.connection.id] = []; }, + testCaptureLogouts: function() { + capturedLogouts = []; + }, + testFetchCapturedLogins: function () { if (capturedLogins[this.connection.id]) { var logins = capturedLogins[this.connection.id]; @@ -62,6 +66,10 @@ Meteor.methods({ } else return []; + }, + + testFetchCapturedLogouts: function() { + return capturedLogouts; } }); @@ -88,6 +96,14 @@ Accounts.onLoginFailure(function (attempt) { } }); +var capturedLogouts = []; + +Accounts.onLogout(function() { + capturedLogouts.push({ + successful: true + }); +}); + // Because this is global state that affects every client, we can't turn // it on and off during the tests. Doing so would mean two simultaneous // test runs could collide with each other. From 9812c135e525ee89561b41a21172bf3e2a780156 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Jun 2016 10:37:48 +1000 Subject: [PATCH 4/4] Added History entry --- History.md | 1 + 1 file changed, 1 insertion(+) diff --git a/History.md b/History.md index ee57ac10a1..ea2ebe65c3 100644 --- a/History.md +++ b/History.md @@ -13,6 +13,7 @@ * Insert a `Date` header into emails by default: https://github.com/meteor/meteor/pull/6916/files * `meteor test` now supports setting the bind address using `--port IP:PORT` the same as `meteor run` [PR #6964](https://github.com/meteor/meteor/pull/6964) [Issue #6961](https://github.com/meteor/meteor/issues/6961) * `Meteor.apply` now takes a `noRetry` option to opt-out of automatically retrying non-idempotent methods on connection blips: [PR #6180](https://github.com/meteor/meteor/pull/6180) +* Adds `Accounts.onLogout()` a hook directly analogous to `Accounts.onLogin()`. [PR #6889](https://github.com/meteor/meteor/pull/6889) ## v1.3.2.3