Rename Accounts.onCreateUserHook to Accounts.insertUserDoc; make it actually

insert the user doc instead of just returning it, and make it (optionally)
generate a login token.
This commit is contained in:
David Glasser
2012-10-06 22:23:20 -07:00
parent 779c2a5036
commit f13c9d18fc
3 changed files with 43 additions and 45 deletions

View File

@@ -128,7 +128,7 @@
return _.extend(user, extra);
};
Accounts.onCreateUserHook = function (options, extra, user) {
Accounts.insertUserDoc = function (options, extra, user) {
// add created at timestamp (and protect passed in user object from
// modification)
user = _.extend({createdAt: +(new Date)}, user);
@@ -164,8 +164,11 @@
throw new Meteor.Error(403, "Email already exists.");
}
var result = {id: Meteor.users.insert(fullUser)};
if (options.generateLoginToken)
result.token = Accounts._loginTokens.insert({userId: result.id});
return fullUser;
return result;
};
var validateNewUserHooks = [];
@@ -204,7 +207,6 @@
var selector = {};
selector["services." + serviceName + ".id"] = serviceData.id;
var user = Meteor.users.findOne(selector);
var result = {};
if (user) {
// don't overwrite existing fields
@@ -214,18 +216,16 @@
var newAttrs = _.pick(extra, newKeys);
Meteor.users.update(user._id, {$set: newAttrs});
}
result.id = user._id;
return {id: user._id,
token: Accounts._loginTokens.insert({userId: user._id})};
} else {
// Create a new user
var servicesClause = {};
servicesClause[serviceName] = serviceData;
user = {services: servicesClause};
user = Accounts.onCreateUserHook(
{services: servicesClause}, extra, user);
result.id = Meteor.users.insert(user);
return Accounts.insertUserDoc(
{services: servicesClause, generateLoginToken: true}, extra, user);
}
result.token = Accounts._loginTokens.insert({userId: result.id});
return result;
};

View File

@@ -39,28 +39,26 @@ Tinytest.add('accounts - updateOrCreateUserFromExternalService', function (test)
});
Tinytest.add('accounts - onCreateUserHook username', function (test) {
Tinytest.add('accounts - insertUserDoc username', function (test) {
var userIn = {
username: Meteor.uuid()
};
// user does not already exist. return a user object with fields set.
var userOut = Accounts.onCreateUserHook(
// user does not already exist. create a user object with fields set.
var result = Accounts.insertUserDoc(
userIn,
{profile: {name: 'Foo Bar'}},
userIn
);
var userOut = Meteor.users.findOne(result.id);
test.equal(typeof userOut.createdAt, 'number');
test.equal(userOut.profile.name, 'Foo Bar');
test.equal(userOut.username, userIn.username);
// insert the user
var uid = Meteor.users.insert(userOut);
// run the hook again. now the user exists, so it throws an error.
test.throws(function () {
Accounts.onCreateUserHook(
Accounts.insertUserDoc(
userIn,
{profile: {name: 'Foo Bar'}},
userIn
@@ -68,11 +66,11 @@ Tinytest.add('accounts - onCreateUserHook username', function (test) {
});
// cleanup
Meteor.users.remove(uid);
Meteor.users.remove(result.id);
});
Tinytest.add('accounts - onCreateUserHook email', function (test) {
Tinytest.add('accounts - insertUserDoc email', function (test) {
var email1 = Meteor.uuid();
var email2 = Meteor.uuid();
var email3 = Meteor.uuid();
@@ -81,24 +79,22 @@ Tinytest.add('accounts - onCreateUserHook email', function (test) {
{address: email2, verified: true}]
};
// user does not already exist. return a user object with fields set.
var userOut = Accounts.onCreateUserHook(
// user does not already exist. create a user object with fields set.
var result = Accounts.insertUserDoc(
userIn,
{profile: {name: 'Foo Bar'}},
userIn
);
var userOut = Meteor.users.findOne(result.id);
test.equal(typeof userOut.createdAt, 'number');
test.equal(userOut.profile.name, 'Foo Bar');
test.equal(userOut.emails, userIn.emails);
// insert the user
var uid = Meteor.users.insert(userOut);
// run the hook again with the exact same emails.
// run the hook again. now the user exists, so it throws an error.
test.throws(function () {
Accounts.onCreateUserHook(
Accounts.insertUserDoc(
userIn,
{profile: {name: 'Foo Bar'}},
userIn
@@ -107,26 +103,26 @@ Tinytest.add('accounts - onCreateUserHook email', function (test) {
// now with only one of them.
test.throws(function () {
Accounts.onCreateUserHook(
Accounts.insertUserDoc(
{}, {}, {emails: [{address: email1}]}
);
});
test.throws(function () {
Accounts.onCreateUserHook(
Accounts.insertUserDoc(
{}, {}, {emails: [{address: email2}]}
);
});
// a third email works.
var user3 = Accounts.onCreateUserHook(
var result3 = Accounts.insertUserDoc(
{}, {}, {emails: [{address: email3}]}
);
test.equal(typeof userOut.createdAt, 'number');
var user3 = Meteor.users.findOne(result3.id);
test.equal(typeof user3.createdAt, 'number');
// cleanup
Meteor.users.remove(uid);
Meteor.users.remove(result.id);
Meteor.users.remove(result3.id);
});

View File

@@ -297,7 +297,8 @@
// if originates in client or server code. Calls user provided hooks,
// does the actual user insertion.
//
// returns userId or throws an error if it can't create
// returns an object with id: userId, and (if options.generateLoginToken is
// set) token: loginToken.
var createUser = function (options, extra) {
extra = extra || {};
var username = options.username;
@@ -328,33 +329,33 @@
if (email)
user.emails = [{address: email, validated: false}];
user = Accounts.onCreateUserHook(options, extra, user);
var userId = Meteor.users.insert(user);
return userId;
return Accounts.insertUserDoc(options, extra, user);
};
// method for create user. Requests come from the client.
Meteor.methods({
createUser: function (options, extra) {
options = _.clone(options);
options.generateLoginToken = true;
if (Accounts._options.forbidSignups)
throw new Meteor.Error(403, "Signups forbidden");
var userId = createUser(options, extra);
// safety belt. createUser is supposed to throw on error. send 500
// error instead of creating a login token with empty userid.
if (!userId)
// Create user. result contains id and token.
var result = createUser(options, extra);
// safety belt. createUser is supposed to throw on error. send 500 error
// instead of sending a validation email with empty userid.
if (!result.id)
throw new Error("createUser failed to insert new user");
// If `Accounts._options.validateEmails` is set, register
// a token to validate the user's primary email, and send it to
// that address.
if (options.email && Accounts._options.validateEmails)
Accounts.sendValidationEmail(userId, options.email);
Accounts.sendValidationEmail(result.id, options.email);
// client gets logged in as the new user afterwards.
var loginToken = Accounts._loginTokens.insert({userId: userId});
this.setUserId(userId);
return {token: loginToken, id: userId};
this.setUserId(result.id);
return result;
}
});
@@ -365,7 +366,8 @@
//
// returns userId or throws an error if it can't create
Accounts.createUser = function (options, extra, callback) {
options = _.clone(options);
options.generateLoginToken = false;
if (typeof extra === "function") {
callback = extra;
extra = {};
@@ -376,7 +378,7 @@
throw new Error("Meteor.createUser with callback not supported on the server yet.");
}
var userId = createUser(options, extra);
var userId = createUser(options, extra).id;
// send email if the user has an email and no password
var user = Meteor.users.findOne(userId);