How to update permissions list with each routing change using CASL in vue 3 with laravel

109 Views Asked by At

I'm using Laravel for the backend and Vuejs 3 for the front end. I wanted to implement authentications on buttons and nav bar routes using CASL v6. I used it fine but I need to refresh the page to get the latest permission, I want to get the latest permissions with every router change.

Here's the app.js

import "./bootstrap";

import { createApp } from "vue";

import App from "./App.vue";

const app = createApp(App);

// CSS Files :: Start
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap";

import "vue-select/dist/vue-select.css";
import "vue-toast-notification/dist/theme-bootstrap.css";

import "./assets/main.css";
// CSS Files :: End

import "./plugins/validator";
import notification from "./plugins/notification";
import filters from "./plugins/filters";
import router from "./router";
import store from "./store";
import vSelect from "vue-select";
import ToastPlugin from "vue-toast-notification";
import VueSplide from "@splidejs/vue-splide";

// Axios :: Start
import axios from "axios";

// axios.defaults.baseURL = "https://soa.connect.ishowcasedc10.com/api/v1/";
axios.defaults.baseURL = "http://localhost:8000/api/v1/";

axios.interceptors.request.use(function (config) {
    const authenticatedUser = store.state.authenticatedUser;
    if (authenticatedUser) {
        const token = store.getters.authenticatedUser.token;
        console.log("token", token);
        config.headers.Authorization = "Bearer " + token;
    }
    return config;
});

axios.interceptors.response.use(null, (error) => {
    if (error.response.status == 401) {
        store.commit("logout");
        router.push("/login");
    }

    return Promise.reject(error.response);
});

window.axios = axios;
// Axios :: End

// Font Awesome Icons
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import "./plugins/icons.js";

// Vue Progress Bar
import VueProgressBar from "@aacassandra/vue3-progressbar";
const progressBarOptions = {
    color: "#bffaf3",
    failedColor: "#874b4b",
    thickness: "5px",
    transition: {
        speed: "0.2s",
        opacity: "0.6s",
        termination: 300,
    },
    autoRevert: true,
    location: "top",
    inverse: false,
};

import { abilitiesPlugin } from "@casl/vue";
import defineAbilities from "@/plugins/ability";

const ability = defineAbilities(axios, app);

app.use(abilitiesPlugin, ability, {
    useGlobalProperties: true,
});

app.config.globalProperties.$filters = filters;

app.use(notification);
app.use(router);
app.use(store);
app.use(VueProgressBar, progressBarOptions);
app.use(ToastPlugin);
app.use(VueSplide);
app.component("font-awesome-icon", FontAwesomeIcon);
app.component("v-select", vSelect);
app.mount("#app");

and here's ability.js file

import { defineAbility } from "@casl/ability";

const defineAbilities = (axios, app) => {
    const ability = defineAbility((can) => {
        // get abilities from the backend
        axios.get(`get-permissions`).then((res) => {
            const permissions = res.data.map((permission) => {
                return { action: permission };
            });

            // Update abilities after getting permissions from the backend
            app.config.globalProperties.$ability.update(permissions);
        }).catch((error) => {
            console.log(error);
        });
    });

    return ability;
};

export default defineAbilities;
0

There are 0 best solutions below