Move login token generation into updateOrCreateUserFromExternalService.

This commit is contained in:
David Glasser
2012-10-05 19:09:50 -07:00
parent 7b758a0c9b
commit 779c2a5036
4 changed files with 19 additions and 25 deletions

View File

@@ -186,7 +186,8 @@
// which is a unique identifier for the user in the service.
// @param extra {Object, optional} Any additional fields to place on the user
// object
// @returns {String} userId
// @returns {Object} Object with token and id keys, like the result
// of the "login" method.
Accounts.updateOrCreateUserFromExternalService = function(
serviceName, serviceData, extra) {
extra = extra || {};
@@ -203,6 +204,7 @@
var selector = {};
selector["services." + serviceName + ".id"] = serviceData.id;
var user = Meteor.users.findOne(selector);
var result = {};
if (user) {
// don't overwrite existing fields
@@ -212,7 +214,7 @@
var newAttrs = _.pick(extra, newKeys);
Meteor.users.update(user._id, {$set: newAttrs});
}
return user._id;
result.id = user._id;
} else {
// Create a new user
var servicesClause = {};
@@ -220,8 +222,10 @@
user = {services: servicesClause};
user = Accounts.onCreateUserHook(
{services: servicesClause}, extra, user);
return Meteor.users.insert(user);
result.id = Meteor.users.insert(user);
}
result.token = Accounts._loginTokens.insert({userId: result.id});
return result;
};

View File

@@ -6,13 +6,13 @@ Tinytest.add('accounts - updateOrCreateUserFromExternalService', function (test)
// create an account with facebook
var uid1 = Accounts.updateOrCreateUserFromExternalService(
'facebook', {id: facebookId}, {foo: 1});
'facebook', {id: facebookId}, {foo: 1}).id;
test.equal(Meteor.users.find({"services.facebook.id": facebookId}).count(), 1);
test.equal(Meteor.users.findOne({"services.facebook.id": facebookId}).foo, 1);
// create again with the same id, see that we get the same user
var uid2 = Accounts.updateOrCreateUserFromExternalService(
'facebook', {id: facebookId}, {foo: 1000, bar: 2}); // foo: 1000 shouldn't overwrite
'facebook', {id: facebookId}, {foo: 1000, bar: 2}).id; // foo: 1000 shouldn't overwrite
test.equal(uid1, uid2);
test.equal(Meteor.users.find({"services.facebook.id": facebookId}).count(), 1);
test.equal(Meteor.users.findOne(uid1).foo, 1);
@@ -24,9 +24,9 @@ Tinytest.add('accounts - updateOrCreateUserFromExternalService', function (test)
// users that have different service ids get different users
uid1 = Accounts.updateOrCreateUserFromExternalService(
'weibo', {id: weiboId1}, {foo: 1});
'weibo', {id: weiboId1}, {foo: 1}).id;
uid2 = Accounts.updateOrCreateUserFromExternalService(
'weibo', {id: weiboId2}, {bar: 2});
'weibo', {id: weiboId2}, {bar: 2}).id;
test.equal(Meteor.users.find({"services.weibo.id": {$in: [weiboId1, weiboId2]}}).count(), 2);
test.equal(Meteor.users.findOne({"services.weibo.id": weiboId1}).foo, 1);
test.equal(Meteor.users.findOne({"services.weibo.id": weiboId1}).emails, undefined);

View File

@@ -49,18 +49,13 @@
// Get the access token for signing requests
oauthBinding.prepareAccessToken(query);
// Get or create user id
// Run service-specific handler.
var oauthResult = service.handleOauthRequest(oauthBinding);
var userId = Accounts.updateOrCreateUserFromExternalService(
service.serviceName, oauthResult.serviceData, oauthResult.extra);
// Generate and store a login token for reconnect
// XXX this could go in accounts_server.js instead
var loginToken = Accounts._loginTokens.insert({userId: userId});
// Store results to subsequent call to `login`
// Get or create user doc and login token for reconnect.
Accounts.oauth._loginResultForState[query.state] =
{token: loginToken, id: userId};
Accounts.updateOrCreateUserFromExternalService(
service.serviceName, oauthResult.serviceData, oauthResult.extra);
}
}

View File

@@ -8,18 +8,13 @@
// Prepare the login results before returning. This way the
// subsequent call to the `login` method will be immediate.
// Get or create user id
// Run service-specific handler.
var oauthResult = service.handleOauthRequest(query);
var userId = Accounts.updateOrCreateUserFromExternalService(
service.serviceName, oauthResult.serviceData, oauthResult.extra);
// Generate and store a login token for reconnect
// XXX this could go in accounts_server.js instead
var loginToken = Accounts._loginTokens.insert({userId: userId});
// Store results to subsequent call to `login`
// Get or create user doc and login token for reconnect.
Accounts.oauth._loginResultForState[query.state] =
{token: loginToken, id: userId};
Accounts.updateOrCreateUserFromExternalService(
service.serviceName, oauthResult.serviceData, oauthResult.extra);
}
// Either close the window, redirect, or render nothing