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?