Reputation: 121
My basic set up is I have a login page, rep page and manager page.
I've set up my routes in iron router and put in some before hooks to verify that there is a user with proper roles. For the login page I want to see if there is a user, what type of user (using roles), and then send along to their proper page if they are already logged in. For the user type pages I want to check if there is a user, make sure they are in the right place, and if not, send them back to the login page or their correct page.
Each user has a role ('rep',organizationId), and an organization in profile.organization. I check what role they have in their organization.
This all works great except when someone resumes a session. If they start from being logged out, it goes swimmingly, but if they logged in yesterday and open the site back up, it just sits at the login page. I think it's because they are re-logging in.
So, question is, what's the best way to handle checking to see if the user is logged in or logging in. The tricky part is I need to grab data from the user profile to determine where to send them, so if they are logging in, I don't think I can do that. I suspect it has something to do with this.redirect('login') vs this.render('login')
Here is my code for the login route
loginsignupController = BaseController.extend ({
layoutTemplate: 'loginLayout',
loadingTemplate: 'loading',
yieldTemplates: {
'header': {to:'header'}
},
before: function() {
//check if logged in
if(!!Meteor.user()){
var org = Meteor.user().profile.organization;
console.log('logged in');
//check for rep, manager
if (Roles.userIsInRole(Meteor.userId(), 'rep', org) || Roles.userIsInRole(Meteor.userId(), 'rep', 'default')){
this.redirect('today')
} else if (Roles.userIsInRole(Meteor.userId(), ['manager'], org)) {
//if manager, send to manager home
this.redirect('managerHome')
}
}
}
});
and here it is for the rep route (user type a)
RepController = BaseController.extend({
layoutTemplate: 'repLayout',
loadingTemplate: 'loading',
yieldTemplates: {
'sidebar': {to: 'sidebar'},
'header': {to:'header'}
},
waitOn: function() {
},
data: function () {
},
before: function(){
//check if logged in
if(!Meteor.loggingIn() && !Meteor.user()) {
this.redirect("/login");
} else {
var org = Meteor.user().profile.organization;
console.log('logged in');
//check for rep, manager
if (Roles.userIsInRole(Meteor.userId(), ['manager'], org)) {
//if manager, send to manager home
this.redirect('/managerHome')
}
};
}})
Thanks!
Upvotes: 0
Views: 576
Reputation: 75975
This behaviour is happening because you've not handled the case where the user's data has not yet arrived from the server.
It works when the user is logged out first, because for them to log in all your subscriptions have to be complete.
So what happens is when you directly load the browser page up, you try to read the user, but the user hasn't yet arrived and it sort of gets stuck. before
isn't reactive so when the user does log in nothing will change.
To fix this you need to publish the user's data and subscribe to it with waitOn
or this.subscribe(..).wait()
in your before.
Another thing to keep in mind is Meteor.user()
changes 3 times during the initial load:
null
until some data arrives from the serverMeteor.user().profile.organization
when Meteor.user().profile
will be null
and it would cause an errorUpvotes: 1