Access Vue instance inside Vue Router Navigation Guard (Vue.js 2) when a page is accessed directly from the URL

Viewed 188

I created 2 plugins, Permission and Authorization:

  • Permission handles the retrieval of all permissions available in the database and expose it to the application by assigning it to a property in the Vue instance.
  • Authorization contains methods that check whether the logged in user has the permission to access certain feature. One of the method is called "isAuthorized" and assigned to a property in the Vue instance.
// Permission.ts
export default class Permissions {
  static install() {
    Vue.prototype.$permissions = new Permission()
  }
  load() {
    // Here the permissions are retrieved from the database and assigned to $permissions
  }
}
// Authorization.ts
export default class Authorization {
  static install() {
    Vue.prototype.$isAuthorized = function (employeePermissions, permissionToBeMatched) {
      // checks if the employee has a permission to a certain feature
      // this.$permissions is accessed in this logic
      return isAuthorized
    }
  }
}

The permissions are then loaded from App.vue.

// App.vue
export default Vue.extend({
  created() {
    this.$permissions.load()
  }
})

Then I can use isAuthorized in my component

// Dashboard.vue
<template>
  <button v-if="canAddSales">Add Sales</button>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
@Component
export default class Dashboard extends Vue {
  // computed
  get canAddSales() {
    this.$isAuthorized(
      this.$store.employeePermissions,
      'sales-add'
    )
  }
}
</script>

I also created a Navigation Guard to prevent user to access pages if the user does not have the sufficient permission

// index.ts for Vue Router
const routes: Array<RouteConfig> = [
  path: '/new/sales',
  name: 'sales.add',
  component: () => import('@/modules/sales/add-sales'),
  beforeEnter: (to, from, next) => {
    const isAuthorized = router.app.$isAddGoalAuthorized(
      router.app.$store.employeePermissions,
      'sales-add'
    )
    if (isAuthorized)
      next()
    else
      next({ name: 'dashboard'})      
  }
]

The problem that I am having is after a user is logged-in then the user attempted to access 'new/sales' page by directly typing the path on the address. In that case, from what I am seeing is the $permissions has not been populated in the Vue instance when it is used inside the Navigation Guard. It looks like to me that the route is processed first then a Vue instance is created. If that is the case then the $permissions does not have data yet since it is called in the "created" lifecycle hook in the App.vue.

How is this situation usually be handled?

0 Answers
Related