2
votes

I use the package: alanning/meteor-roles

I am building a simple UI for Admin to manage other users roles. A user can have more than one role, I am using checkbox to choose roles.

The problem I am facing is that I am unable to access the roles array that is stored in Meteor.users collection in my Client code.

In a helper, I am checking the user roles in order to load it in the UI as checked...

Note: this HTML is accessible for all users now just to test it. It will be available only for Admin after I get it to work. So I noticed that this code works only for signed in user and not for all users.

My code:

HTML:

<label class="checkbox-inline"><input type="checkbox" class="userRole" value="r1" checked="{{isRoleChecked 'r1'}}">r1</label>
<label class="checkbox-inline"><input type="checkbox" class="userRole" value="r2" checked="{{isRoleChecked 'r2'}}">r2</label>
<label class="checkbox-inline"><input type="checkbox" class="userRole" value="r3" checked="{{isRoleChecked 'r3'}}">r3</label>
<label class="checkbox-inline"><input type="checkbox" class="userRole" value="r4" checked="{{isRoleChecked 'r4'}}">r4</label>
<label class="checkbox-inline"><input type="checkbox" class="userRole" value="r5" checked="{{isRoleChecked 'r5'}}">r5</label>
<label class="checkbox-inline"><input type="checkbox" class="userRole" value="r6" checked="{{isRoleChecked 'r6'}}">r6</label>

isRoleChecked helper: (Client code)

isRoleChecked: function(value) {

  // didn't work
  roles = Roles.getRolesForUser(this._id);
  if (roles) {
    for(var i=0; i < roles.length; i++) {
      if (roles[i] == value){
        return true;
      } else {
        return false;
      }
    }
  }
},
2

2 Answers

3
votes

By default Meteor does not publish data outside profile for Meteor.users collection, except for the current user. The rationale is to make sure sensitive data is always hidden.

If the autopublish package is installed, information about all users on the system is published to all clients. This includes* username, profile, and any fields in services that are meant to be public (eg services.facebook.id, services.twitter.screenName). Additionally, when using autopublish more information** is published for the currently logged in user, including access tokens.

(source: https://docs.meteor.com/api/accounts.html#Meteor-users)

* means other fields are excluded, therefore roles is not published by autopublish.

** this includes roles field for the current user.

That is why your code works only for the current user.

Therefore you just need to setup a publication (and subscribe to it) that explicitly sends the roles field of your users to the client:

Meteor.publish('usersRoles', function () {
  return Meteor.users.find(mySelector, {
    fields: {
      roles: 1
    }
  });
});
1
votes

You need to publish the roles key:

Server:

Meteor.publish('roles',() => {
  if ( Roles.userIsInRole(this.userId,['Admin']) {
    return Meteor.users.find({},{fields: {roles: 1}});
  } else this.ready();
});

And subscribe to that on the client:

Meteor.subscribe('roles');