I had to figure this out as well but not so much for chat or rooms but more so for more fine grained control over user accounts, who is online and what they can or can't do based on date/time. The principles are the same.
Create a boolean field loggedIn on the user record OR have a separate collection of logged in users (logged_in_users or something).
In order to do this, I had to create a preLogin and postLogin hook on auth branch. So, I created PR 270
I needed to know about the user login attempt either before or after login. Specifically in my case, I have another field on the user record called active (boolean) because my application needs the ability to activate/deactivate users and prevent them from logging in rather than just deleting/removing them.
So, unfortunately my solution relies on the PR 270 I built. A little self serving nudge for votes for my PR on the auth branch ;). But it works and will help solve your problem in a more Meteor oriented way of using collections and publishing and subscribing.
First, I make sure their account is active. Which is a field they cannot update themselves only Administrators can. This is a field I added to the users collection and is not part of Meteor right now. I found it important to have active/inactive user accounts instead of relying on removing/deleting accounts. According to the Meteor docs and comments on the auth branch docs they suggest we feel free to add fields to the user records aka extras.
This is in my code now and prevents user logins unless the account is active. This checks sessions that are resuming where the user is already logged in. It is important to understand the Meteor auth branch session resume functionality, which is why I built this hook.
Meteor.accounts.preLogin(function(options){
if(options.resume){
var loginToken = Meteor.accounts._loginTokens.findOne({_id: options.resume});
if (loginToken){
if(!Meteor.users.findOne({_id: loginToken.userId, active: true})){
return false;
} else {
// Maybe update that they are back online and what rooms they are in
// Great way to welcome them back, could even show them what happened while they were gone.
}
}
return true;
});
Second, I also check it on postLogin which is where you can decide how you want to keep track of your list of logged in users.
This is in my code now and also prevents login unless the account is active.
Meteor.accounts.postLogin(function(result){
if(!Meteor.users.findOne({_id:
result.id, active: true})){
return false;
} else {
// SET user field to loggedIn = true or put in Collection of say logged_in_users or something
return true;
}
});
At some point I am going to have to look at automatic timed log out server side. And also at some point look at a notification hook for client log out. Both are needed in auth branch. I just haven't gotten to that point in my application yet.
If you did the logged_in_users as a separate collection of logged in users and published it then you wouldn't have to risk publishing all Meteor.users data to all clients. You could then publish say just name and _id and maybe a subfield collection of rooms they are current in (if they can be in more room than one). This would allow you to do private messages/1 on 1 chat as well in addition to room chat. You could let users go invisible and such. And since it would be published to all logged in users, it would meteormagically update and everyone would know where everyone else is at any moment. You could still limit message delivery to room subscriptions to keep data wire transfer down.
If you fiddle around with a logout hook or a server side timed hook that auto-logs out users please keep me notified. I am going to need that at some point myself.
Hope this helps a bit.
Steeve