After spending two days trying to figure it out, I realized that I may be missing something simple.
In my Vue application, I am using casl-vue to control what users can see or do based on their roles.
I want to set the ability in two instances: when the page loads and after a user logs in.
On page load
Everything works fine when I register the abilities synchronously like this:
main.js
import { abilitiesPlugin } from '@casl/vue';
import ability from '../config/ability';
Vue.use(abilitiesPlugin, ability);
ability.js
import { AbilityBuilder, Ability } from '@casl/ability';
export default AbilityBuilder.define((can, cannot) => {
const role = 'Admin';
switch (role) {
case 'Admin':
can('manage', 'all');
break;
case 'Author':
can('manage', 'all');
cannot('manage', 'users');
break;
case 'Trainer':
break;
case 'Participant':
cannot('manage', 'all');
break;
default:
cannot('manage', 'all');
};
})
However, when I try to get the role using a function that returns a promise (getCurrentUserRole()) and make the function async like this:
ability.js
export default AbilityBuilder.define(async (can, cannot) => {
const role = await getCurrentUserRole();
switch (role) {
case 'Admin':
can('manage', 'all');
break;
...
default:
cannot('manage', 'all');
};
})
I encounter the error: "TypeError: ability.on is not a function"
After login
Updating the ability rules after login works using this.$ability.update:
const { role } = await someSignInFunction();
this.$ability.update(defineRulesFor(role));
this.$router.push({ name: 'home' });
Unfortunately, I can't use this function on page load because by the time I call ability.update in App.vue (for example, in beforeCreate()
or created()
), the page has already loaded, making the update too late.
Vue router
I also want to access the ability can method in my Vue Router instance to control the routes users can visit. But how do I access the ability instance in my router file?
If I haven't explained my problem clearly, please let me know!
Any help with setting up this structure would be greatly appreciated.
Dependencies:
casl/ability: ^3.3.0
casl/vue: ^0.5.1