I'm trying to use the 'roles' package available on Atmosphere but I can't get it to work with Accounts.onCreateUser(), I can get the example on github. When I register a user, I want to add a role to them, when I test whether the role is assigned, it's not picking it up.
Here's my code
/server/users.js
Accounts.onCreateUser(function(options, user){
var role = ['admin'];
Roles.addUsersToRoles(user, role);
return user;
});
/client/page.js
Template.hello.events({
'click input': function () {
var loggedInUser = Meteor.user();
if (Roles.userIsInRole(loggedInUser, ['admin'])) {
console.log("Hi Admin!");
}else{
console.log("Please Log In");
}
}
});
I way I found to do this and it's pretty simple.
I am passing role as an array, so I used [role]
On client-side, when the user signs up:
In our meteor methods (I am using lodash intersect method to verify the role I want user to choose)
I didn't want to rewrite logic given by Meteor's accounts packages, set the ID myself, or use setTimeout.
Instead I have Tracker code watching the
Meteor.user()
call, which returns the user if logged in and null if not.So, effectively, once a user has logged in, this code will check to see if they've been assigned a role and if they haven't add them.
I did have to use a Meteor method because I don't want roles to be messed with client side, but you can change that.
If you look at the code being used in the
Roles
package you will see that they use your passed in user/userId to perform a query on the user's collection (here, starting at line ~623):Since
onCreateUser
is called before the user object is inserted into the collection (docs: The returned document is inserted directly into the Meteor.users collection),Roles
cannot find it when it performs the query.In order to fix this you must wait until the user is inserted into the collection. If you look at the
Roles
package all of their examples show this. Like here, (second example, comments added), along with many others:Hope that shines some light on your issue. So basically just insert the user and then add the permissions after.
I don't understand how to integrate Roles.addUsersToRoles with the onCreateUser function called when a user is created. It doesn't work when it's called within OnCreateUser as you've done, as you've found. But the example case of calling addUsersToRoles within a user creation loop doesn't seem applicable to the normal use case of a new user creating an account.
Instead, I just do:
To add things to a user document after it has been inserted by the
accounts
package, try this pattern. Note, you mustmeteor add random
in order to generate auserId
, which is safe to do in this context.The issue here really comes down to looking for a post create user hook (which
onCreateUser
is not).It turns out, such a thing exists! It's called the
postSignUpHook
.https://github.com/meteor-useraccounts/core/blob/master/Guide.md#options
I found this from this SO answer:
https://stackoverflow.com/a/34114000/3221576
This is the preferred method for adding roles to a user created with the boilerplate UserAccounts package (i.e. if you're not rolling your own with
Accounts.createUser
).UPDATE
Ultimately I ended up using matb33:collection-hooks as per this comment:
https://github.com/alanning/meteor-roles/issues/35#issuecomment-198979601
Just stick that code in your Meteor.startup and things work as expected.