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

Meteor.user().roles undefined in SSR #216

Closed neopostmodern closed 5 years ago

neopostmodern commented 8 years ago

METEOR@1.4.1.1 / alanning:roles@1.2.15

I'm having issues with SSR. I checked all this, but the example repo doesn't feature SSR and the talk also didn't seem to touch my issues.

A small code snippet to point out my issue would be:

Meteor.publish(Meteor.users.PUBLICATIONS.ALL, function () {
  if (!Roles.userIsInRole(this.userId, ['users'])) {
    // todo: could possibly still return own user `Meteor.users.find(this.userId)`
    return [];
  }

  return Meteor.users.find();
});

// ...

class AdminLayout extends React.Component {
  static propTypes = {
    loggingIn: PropTypes.bool,
    authorized: PropTypes.bool,
    user: PropTypes.object,
    // ...
  };

  // ...
}

function composer(props, onData) {  
  if (Meteor.isClient && Meteor.loggingIn() || (Meteor.userId() && !Meteor.user())) { // basically "logging in"
    return onData({ loggingIn: true, ...props }, null);
  }

  const user = Meteor.user();
  console.log("1 - User", user);
  console.log("1 - User (db)", Meteor.users.findOne(user._id));
  console.log("1 - User (db + fields)", Meteor.users.findOne(user._id, { fields: { roles: 1 } }));
  console.log("1 - Roles", Roles.userIsInRole(user._id, 'content'));
  console.log("1 - Roles for user", Roles.getRolesForUser(user._id));
  Meteor.subscribe(Meteor.users.PUBLICATIONS.ALL);
  const user2 = Meteor.user();
  console.log("2 - User", user2);
  console.log("2 - User (db)", Meteor.users.findOne(user2._id));
  console.log("2 - User (db + fields)", Meteor.users.findOne(user2._id, { fields: { roles: 1 } }));
  console.log("2 - Roles", Roles.userIsInRole(user2._id, 'content'));
  console.log("2 - Roles for user", Roles.getRolesForUser(user2._id));

  onData(null, {
    user,
    authorized: Roles.userIsInRole(user._id, 'content'),
    ...props
  });
}

export default composeWithTracker(composer)(AdminLayout)

Which on the server logs

I20160917-17:35:52.818(2)? 1 - User { _id: 'qMhbLJrinNRoaxdtg',
I20160917-17:35:52.818(2)?   emails: [ { address: '...@....com', verified: false } ],
I20160917-17:35:52.819(2)?   username: 'neopostmodern' }
I20160917-17:35:52.820(2)? 1 - User (db) { _id: 'qMhbLJrinNRoaxdtg',
I20160917-17:35:52.821(2)?   emails: [ { address: '...@....com', verified: false } ],
I20160917-17:35:52.821(2)?   username: 'neopostmodern' }
I20160917-17:35:52.821(2)? 1 - User (db + fields) { _id: 'qMhbLJrinNRoaxdtg' }
I20160917-17:35:52.822(2)? 1 - Roles false
I20160917-17:35:52.822(2)? 1 - Roles for user []
I20160917-17:35:52.825(2)? 2 - User { _id: 'qMhbLJrinNRoaxdtg',
I20160917-17:35:52.825(2)?   emails: [ { address: '...@....com', verified: false } ],
I20160917-17:35:52.826(2)?   username: 'neopostmodern',
I20160917-17:35:52.826(2)?   createdAt: Sun Sep 11 2016 02:29:49 GMT+0200 (CEST),
I20160917-17:35:52.826(2)?   services: 
I20160917-17:35:52.826(2)?    { password: { bcrypt: '...' },
I20160917-17:35:52.827(2)?      resume: { loginTokens: [Object] } },
I20160917-17:35:52.827(2)?   roles: [ 'user', 'content', 'users', 'identified' ] }
I20160917-17:35:52.827(2)? 2 - User (db) { _id: 'qMhbLJrinNRoaxdtg',
I20160917-17:35:52.827(2)?   emails: [ { address: '...@....com', verified: false } ],
I20160917-17:35:52.827(2)?   username: 'neopostmodern',
I20160917-17:35:52.828(2)?   createdAt: Sun Sep 11 2016 02:29:49 GMT+0200 (CEST),
I20160917-17:35:52.828(2)?   services: 
I20160917-17:35:52.828(2)?    { password: { bcrypt: '...' },
I20160917-17:35:52.828(2)?      resume: { loginTokens: [Object] } },
I20160917-17:35:52.828(2)?   roles: [ 'user', 'content', 'users', 'identified' ] }
I20160917-17:35:52.837(2)? 2 - User (db + fields) { roles: [ 'user', 'content', 'users', 'identified' ],
I20160917-17:35:52.837(2)?   _id: 'qMhbLJrinNRoaxdtg' }
I20160917-17:35:52.837(2)? 2 - Roles true
I20160917-17:35:52.837(2)? 2 - Roles for user [ 'user', 'content', 'users', 'identified' ]

On the client 1 and 2 are equal (and correct, i.e. include roles and can rell if they are in a group).

So, long story short - Meteor.user() doesn't seem to include the roles field when doing SSR. No idea if this is related to this package or something very different, but it makes things kind of arbitrary and very un-isomorphic.

danielmain commented 6 years ago

Im having the same issue, did you find out why?

neopostmodern commented 6 years ago

No, I've sticked with above.

vuhrmeister commented 6 years ago

I'm having a similar problem. Or let's say it's the reason why Meteor.user().roles does not work.

Meteor.user() or Meteor.userId() needs to be run in a fiber. What I just came up with is wrapping that in a method. Don't know if that's the best approach, but it works for now.

Meteor.methods({
  'user' () {
    return Meteor.user()
  }
})

And then instead of just calling Meteor.user() you call Meteor.call('user').

JonathanLehner commented 5 years ago

any updates on this?

mitar commented 5 years ago

Please provide a reproduction for this. Also test please with latest version. I can reopen the issue then.