mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Remove all other tokens when a connection calls changePassword
This commit is contained in:
@@ -198,10 +198,18 @@ Meteor.methods({changePassword: function (options) {
|
||||
if (!verifier)
|
||||
throw new Meteor.Error(400, "Invalid verifier");
|
||||
|
||||
// XXX this should invalidate all login tokens other than the current one
|
||||
// (or it should assign a new login token, replacing existing ones)
|
||||
// It would be better if this removed ALL existing tokens and replaced
|
||||
// the token for the current connection with a new one, but that would
|
||||
// be tricky, so we'll settle for just replacing all tokens other than
|
||||
// the one for the current connection.
|
||||
var currentToken = Accounts._getLoginToken(this.connection.id);
|
||||
Meteor.users.update({_id: this.userId},
|
||||
{$set: {'services.password.srp': verifier}});
|
||||
{
|
||||
$set: { 'services.password.srp': verifier },
|
||||
$pull: {
|
||||
'services.resume.loginTokens': { hashedToken: { $ne: currentToken } }
|
||||
}
|
||||
});
|
||||
|
||||
var ret = {passwordChanged: true};
|
||||
if (serialized)
|
||||
|
||||
@@ -191,6 +191,65 @@ if (Meteor.isClient) (function () {
|
||||
logoutStep
|
||||
]);
|
||||
|
||||
testAsyncMulti("passwords - changing password logs out other clients", [
|
||||
function (test, expect) {
|
||||
this.username = Random.id();
|
||||
this.email = Random.id() + '-intercept@example.com';
|
||||
this.password = 'password';
|
||||
this.password2 = 'password2';
|
||||
Accounts.createUser(
|
||||
{ username: this.username, email: this.email, password: this.password },
|
||||
loggedInAs(this.username, test, expect));
|
||||
},
|
||||
// Log in a second connection as this user.
|
||||
function (test, expect) {
|
||||
var self = this;
|
||||
|
||||
// copied from livedata/client_convenience.js
|
||||
var ddpUrl = '/';
|
||||
if (typeof __meteor_runtime_config__ !== "undefined") {
|
||||
if (__meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL)
|
||||
ddpUrl = __meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL;
|
||||
}
|
||||
// XXX can we get the url from the existing connection somehow
|
||||
// instead?
|
||||
|
||||
self.secondConn = DDP.connect(ddpUrl);
|
||||
self.secondConn.call('login',
|
||||
{ user: { username: self.username }, password: self.password },
|
||||
expect(function (err, result) {
|
||||
test.isFalse(err);
|
||||
self.secondConn.setUserId(result.id);
|
||||
test.isTrue(self.secondConn.userId());
|
||||
|
||||
self.secondConn.onReconnect = function () {
|
||||
self.secondConn.apply(
|
||||
'login',
|
||||
[{ resume: result.token }],
|
||||
{ wait: true },
|
||||
function (err, result) {
|
||||
self.secondConn.setUserId(result && result.id || null);
|
||||
}
|
||||
);
|
||||
};
|
||||
}));
|
||||
},
|
||||
function (test, expect) {
|
||||
var self = this;
|
||||
Accounts.changePassword(self.password, self.password2, expect(function (err) {
|
||||
test.isFalse(err);
|
||||
}));
|
||||
},
|
||||
// Now that we've changed the password, wait until the second
|
||||
// connection gets logged out.
|
||||
function (test, expect) {
|
||||
var self = this;
|
||||
pollUntil(expect, function () {
|
||||
return self.secondConn.userId() === null;
|
||||
}, 10 * 1000, 100);
|
||||
}
|
||||
]);
|
||||
|
||||
|
||||
testAsyncMulti("passwords - new user hooks", [
|
||||
function (test, expect) {
|
||||
|
||||
Reference in New Issue
Block a user