Skip to content

Commit

Permalink
Merge branch 'devel' into release-0.6.6
Browse files Browse the repository at this point in the history
  • Loading branch information
n1mmy committed Oct 8, 2013
2 parents 77d50e4 + 9f2188b commit 3798826
Show file tree
Hide file tree
Showing 22 changed files with 1,082 additions and 245 deletions.
5 changes: 5 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
* Improve behavior of `$ne`, `$nin`, and `$not` selectors with objects containing
arrays. #1451

* `$near` operator for `2d` and `2dsphere` indices.

#### DDP

* Fix infinite loop if a client disconnects while a long yielding method is
Expand Down Expand Up @@ -67,6 +69,9 @@

* Warn if `Accounts.config` is only called on the client. #828

* Fix bug where callbacks to login functions could be called multiple
times when the client reconnects.

#### Tools

* The pre-0.6.5 `Package.register_extension` API has been removed. Use
Expand Down
5 changes: 5 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,11 @@ uid2: https://github.com/coreh/uid2

Copyright (c) 2013 Marco Aurelio

----------
geojson-utils: https://github.com/maxogden/geojson-js-utils
----------

Copyright (c) 2010 Max Ogden

==============
Apache License
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ From your checkout, you can read the docs locally. The `/docs` directory is a
meteor application, so simply change into the `/docs` directory and launch
the app:

cd docs/
meteor
cd docs/
../meteor

You'll then be able to read the docs locally in your browser at
`http://localhost:3000/`
Expand Down
10 changes: 6 additions & 4 deletions packages/accounts-base/accounts_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ Accounts.callLoginMethod = function (options) {
if (!options[f])
options[f] = function () {};
});
// make sure we only call the user's callback once.
var onceUserCallback = _.once(options.userCallback);

var reconnected = false;

Expand Down Expand Up @@ -116,7 +118,7 @@ Accounts.callLoginMethod = function (options) {
if (error) {
makeClientLoggedOut();
}
options.userCallback(error);
onceUserCallback(error);
}});
}
};
Expand All @@ -142,19 +144,19 @@ Accounts.callLoginMethod = function (options) {
if (error || !result) {
error = error || new Error(
"No result from call to " + options.methodName);
options.userCallback(error);
onceUserCallback(error);
return;
}
try {
options.validateResult(result);
} catch (e) {
options.userCallback(e);
onceUserCallback(e);
return;
}

// Make the client logged in. (The user data should already be loaded!)
makeClientLoggedIn(result.id, result.token, result.tokenExpires);
options.userCallback();
onceUserCallback();
};

if (!options._suppressLoggingIn)
Expand Down
23 changes: 17 additions & 6 deletions packages/accounts-base/accounts_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,22 +197,33 @@ var removeLoginToken = function (userId, loginToken) {
var expireTokenInterval;

// Deletes expired tokens from the database and closes all open connections
// associated with these tokens. Exported for tests. oldestValidDate is used
// only by tests to simulate expiring tokens without waiting for them to
// actually expire.
var expireTokens = Accounts._expireTokens = function (oldestValidDate) {
// associated with these tokens.
//
// Exported for tests. Also, the arguments are only used by
// tests. oldestValidDate is simulate expiring tokens without waiting
// for them to actually expire. userId is used by tests to only expire
// tokens for the test user.
var expireTokens = Accounts._expireTokens = function (oldestValidDate, userId) {
var tokenLifetimeMs = getTokenLifetimeMs();

// when calling from a test with extra arguments, you must specify both!
if ((oldestValidDate && !userId) || (!oldestValidDate && userId)) {
throw new Error("Bad test. Must specify both oldestValidDate and userId.");
}

oldestValidDate = oldestValidDate ||
(new Date(new Date() - tokenLifetimeMs));
var userFilter = userId ? {_id: userId} : {};


// Backwards compatible with older versions of meteor that stored login token
// timestamps as numbers.
Meteor.users.update({
Meteor.users.update(_.extend(userFilter, {
$or: [
{ "services.resume.loginTokens.when": { $lt: oldestValidDate } },
{ "services.resume.loginTokens.when": { $lt: +oldestValidDate } }
]
}, {
}), {
$pull: {
"services.resume.loginTokens": {
$or: [
Expand Down
2 changes: 1 addition & 1 deletion packages/accounts-base/accounts_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,5 +206,5 @@ Tinytest.addAsync('accounts - expire numeric token', function (test, onComplete)
}
}
});
Accounts._expireTokens(new Date());
Accounts._expireTokens(new Date(), result.id);
});
43 changes: 30 additions & 13 deletions packages/accounts-password/password_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -316,20 +316,35 @@ Meteor.methods({resetPassword: function (token, newVerifier) {

var stampedLoginToken = Accounts._generateStampedLoginToken();

// Update the user record by:
// - Changing the password verifier to the new one
// - Replacing all valid login tokens with new ones (changing
// password should invalidate existing sessions).
// - Forgetting about the reset token that was just used
// - Verifying their email, since they got the password reset via email.
Meteor.users.update({_id: user._id, 'emails.address': email}, {
$set: {'services.password.srp': newVerifier,
'services.resume.loginTokens': [stampedLoginToken],
'emails.$.verified': true},
$unset: {'services.password.reset': 1}
});
// NOTE: We're about to invalidate tokens on the user, who we might be
// 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 = this._getLoginToken();
this._setLoginToken(null);

try {
// Update the user record by:
// - Changing the password verifier to the new one
// - Replacing all valid login tokens with new ones (changing
// password should invalidate existing sessions).
// - Forgetting about the reset token that was just used
// - Verifying their email, since they got the password reset via email.
Meteor.users.update({_id: user._id, 'emails.address': email}, {
$set: {'services.password.srp': newVerifier,
'services.resume.loginTokens': [stampedLoginToken],
'emails.$.verified': true},
$unset: {'services.password.reset': 1}
});
} catch (err) {
// update failed somehow. reset to old token.
this._setLoginToken(oldToken);
throw err;
}

this._setLoginToken(stampedLoginToken.token);
this.setUserId(user._id);

return {
token: stampedLoginToken.token,
tokenExpires: Accounts._tokenExpiration(stampedLoginToken.when),
Expand Down Expand Up @@ -421,6 +436,7 @@ Meteor.methods({verifyEmail: function (token) {
$push: {'services.resume.loginTokens': stampedLoginToken}});

this.setUserId(user._id);
this._setLoginToken(stampedLoginToken.token);
return {
token: stampedLoginToken.token,
tokenExpires: Accounts._tokenExpiration(stampedLoginToken.when),
Expand Down Expand Up @@ -499,6 +515,7 @@ Meteor.methods({createUser: function (options) {

// client gets logged in as the new user afterwards.
this.setUserId(result.id);
this._setLoginToken(result.token);
return result;
}});

Expand Down Expand Up @@ -533,5 +550,5 @@ Accounts.createUser = function (options, callback) {
///
Meteor.users._ensureIndex('emails.validationTokens.token',
{unique: 1, sparse: 1});
Meteor.users._ensureIndex('emails.password.reset.token',
Meteor.users._ensureIndex('services.password.reset.token',
{unique: 1, sparse: 1});
Loading

0 comments on commit 3798826

Please sign in to comment.