question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Meteor.user() isn't ready in triggersEnter function when user clicks on bookmarked link

See original GitHub issue

I want to turn off access to a bunch of admin routes if the user is not logged in or doesn’t have sufficient priveledges. I’ve got it working in most instances using a FlowRouter group and triggersEnter. However, I’m having a problem in the below code.

// Admin routes group
const adminRoutes = FlowRouter.group({
  prefix: '/admin',
  name: 'admin',
  triggersEnter: [(context, redirect) => {
    if (!Meteor.user() || Meteor.user().username !== 'admin') {
      redirect('/not-authorized');
    }
  }],
});

It works perfectly in all situations except when:

  • The client refreshes, or
  • The goes to the route by clicking a saved link (ie bookmark or email etc)

The problem seems to be that Meteor.user() isn’t available yet when the trigger runs. I’ve experimented with different Tracker autorun options but they don’t seem to work.

I’ve created a repro here: https://github.com/proehlen/admin-pages-route-group-redirect.

Relevant code is in /imports/startup/client/routing.js starting at line 28.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:3
  • Comments:9

github_iconTop GitHub Comments

1reaction
KaitaniLabscommented, Feb 23, 2017

There is a pretty simple solution to this which I’m using:

// Logged In Routes Group
loggedInRoutes = exposedRoutes.group({
  prefix: '',
  name: 'loggedIn',
  triggersEnter: [function(context, redirect) {
    if(!Meteor.loggingIn() && !Meteor.userId()){
      let route = FlowRouter.current();
      if(route.route.name !== "Login"){
        Session.set("redirectAfterLogin",route.path);
        redirect('/login');
      }
    }
  }]
});

// Admin Routes Group (extends Logged In Routes)
adminRoutes = loggedInRoutes.group({
  prefix: '/admin',
  name: 'admin'
});

// Example Admin Route
adminRoutes.route('/dashboard', {
  name: "AdminDashboard",
  action: function () {
    BlazeLayout.render('AdminLayout', {topbar: 'AdminTopbar',content: 'AdminDashboard'});
  }
});

// AdminLayout is a layout template, but it is still a template so use the onCreated hook
Template.AdminLayout.onCreated(function() {
  const instance = this;
  instance.autorun(function () {
    var subscription = instance.subscribe('userData');
    if (subscription.ready()) {
      /**
       * Do your check here for access
       * E.g. if(user doesn't have access){FlowRouter.go("Some route for non-admins");}
       */
    }
  });
});

// AdminLayout Template
<template name="AdminLayout">
  {{#if Template.subscriptionsReady}}	
    {{>Template.dynamic template=topbar}}
    {{>Template.dynamic template=content}}
  {{else}}
{{> Loading}}
  {{/if}}
</template>

// Publish userData
Meteor.publish("userData",function(){
  if(this.userId){
    return Meteor.users.find({_id : this.userId});	
  }else{
    this.ready();
  }
});

This removes subscriptions from the Router making it do what it’s supposed to do and nothing more. Since all of your admin templates will use the same layout (or at least they probably should) the above code will work for any new admin routes you add to an app so long as the layout is ‘AdminLayout’.

Because Admin Routes group extends LoggedIn Routes group the triggersEnter get used automatically. So there is no need to check for Meteor.loggingIn() or Meteor.userId() in the Admin Routes group.

Hope that helps 😃

0reactions
proehlencommented, Feb 23, 2017

I’ve moved on since the issue was raised to another platform for the project that prompted it so closing this issue. Thanks @Allerion for posting your work around. I’m sure it will come in handy for others facing this problem.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Trigger event when new user is created - how to do? - help
I am using accounts-password and accounts-ui. ... Meteor.users.after.insert(function () { var targetsId = Targets.insert({userId: this.
Read more >
Meteor/React - How to wait for Meteor.user() - Stack Overflow
Meteor.user() will be undefined inside the component before loading so make sure you prevent it's calling by adding a condition such as ...
Read more >
A Beginner's Meteor Tutorial: Build Real-Time Web Apps | Toptal
It makes developing web applications simple. It is easy to learn, and it lets you focus more on the functionality of your application...
Read more >
Andor iQ USER GUIDE
By default, iQ Application User Accounts are not switched on and the iQ ... To run the Configuration Manager, click on its icon...
Read more >
Chapter 7. Exchanging data - Meteor in Action
Angilla Meteor.subscribe() rruenst cn jtceob jwru z stop() nzp c ready() dtmohe. ... Regardless of whether a user views the subscription data, the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found