Meteor-Community-Packages / meteor-roles

Authorization package for Meteor, compatible with built-in accounts packages
http://meteor-community-packages.github.io/meteor-roles/
MIT License
921 stars 168 forks source link

Default role of user created from client #181

Closed trajano closed 8 years ago

trajano commented 8 years ago

Similar to #35 but I want to do it from the client side. I tried to follow the examples on #35 but it didn't work. This is the closest that I can make it run but it fails in the end with an update failed: Access denied.

The approach I was taking was to do it via callback event since that is the only time I can be sure that the user was created or had an explicit error. I have verified that there are values in the console log.

In fact for a short while the user does have that role, but the update gets rolled back due to update failed.

Template.createAdminUserPage.events({
    'submit form': function (event, template) {
        event.preventDefault();
        var email = $('[name=email]').val();
        var password = $('[name=password]').val();

        Accounts.createUser({email: email, password: password}, function (err) {
            if (err) {
                console.log(err);
            } else {
                console.log("user id = "  + Meteor.userId());
                console.log("user = "  + Meteor.user());
                Roles.addUsersToRoles(Meteor.user(), 'admin');
            }
        });
    }
});
trajano commented 8 years ago

I found a bit of a workaround, but seems to work. The idea is to do the job on the server which is what is done on #35 to begin with. I used a the Meteor.call on the client to call a Meteor.methods on the server. Keeping it open for now in case there is a correct way of doing it on the client side that I am missing. (Apologies I just started learning Meteor last week while I was stuck at home with a cold).

Meteor.methods({
    /**
     * This will create the initial admin user.  This will only work if one does not presently exist, if one does exist it will throw an error.
     * @param email
     * @param password
     */
    createInitialAdminUser: function (email, password) {
        if (Roles.getUsersInRole('admin', null, {reactive: false, limit: 1}).count() != 0) {
            throw new Meteor.Error("An existing admin user is already present");
        }
        var userId = Accounts.createUser({email: email, password: password});
        Roles.addUsersToRoles(userId, ['admin']);
    },
    /**
     * 
     * @returns {boolean} true if there is at least one admin user
     */
    hasAdminUser: function() {
        var c = Roles.getUsersInRole('admin', null, {reactive: false, limit: 1}).count();
        return c != 0;
    }
});
mitar commented 8 years ago

Yes, in fact the best way is to add do all changes inside Meteor methods.