<script setup lang="ts"> import { onBeforeMount, onMounted } from "vue"; import { useCookies } from "vue3-cookies"; import { useAuthStore } from "@/stores/users"; import { useRoute, useRouter } from "vue-router"; import { OpenAPI as S3ProxyOpenAPI } from "@/client/s3proxy"; import { OpenAPI as AuthOpenAPI } from "@/client/auth"; import { OpenAPI as WorkflowOpenAPI } from "@/client/workflow"; import { OpenAPI as ResourceOpenAPI } from "@/client/resource"; import { environment } from "@/environment"; import axios from "axios"; import { useNameStore } from "@/stores/names"; import AppHeader from "@/components/AppHeader.vue"; import AppFooter from "@/components/AppFooter.vue"; import { useResourceStore } from "@/stores/resources"; import { useWorkflowStore } from "@/stores/workflows"; import { useBucketStore } from "@/stores/buckets"; import { useS3KeyStore } from "@/stores/s3keys"; const { cookies } = useCookies(); const router = useRouter(); const route = useRoute(); const userRepository = useAuthStore(); const nameRepository = useNameStore(); const resourceRepository = useResourceStore(); const workflowRepository = useWorkflowStore(); const bucketRepository = useBucketStore(); const s3KeyRepository = useS3KeyStore(); onBeforeMount(() => { S3ProxyOpenAPI.BASE = environment.S3PROXY_API_BASE_URL; AuthOpenAPI.BASE = environment.AUTH_API_BASE_URL; WorkflowOpenAPI.BASE = environment.WORKFLOW_API_BASE_URL; ResourceOpenAPI.BASE = environment.RESOURCE_API_BASE_URL; axios.interceptors.response.use( (res) => res, (err) => { if ( (err.response.status === 400 || err.response.status === 403) && err.response.data.detail?.includes("JWT") ) { userRepository.logout(); cookies.remove("bearer"); router.push({ name: "login", query: { login_error: err.response.status === 400 ? "token_invalid" : "token_expired", return_path: route.name != "login" ? encodeURI(route.path) : undefined, }, }); } return Promise.reject(err); }, ); userRepository.setToken(cookies.get("bearer")); router.afterEach((to, from) => { window._paq.push(["setReferrerUrl", from.path]); window._paq.push(["deleteCustomVariables", "page"]); window._paq.push(["deleteCustomDimension", 1]); window._paq.push(["setCustomUrl", to.path]); window._paq.push(["setDocumentTitle", to.name]); if (userRepository.currentUID.length > 0) { window._paq.push(["setUserId", userRepository.currentUID]); } window._paq.push(["trackPageView"]); window._paq.push(["enableLinkTracking"]); }); router.beforeEach(async (to) => { // make sure the user is authenticated if ( !userRepository.authenticated && // ❗️ Avoid an infinite redirect to.name !== "login" ) { // redirect the user to the login page and preserve query params for login error message return { name: "login", query: { ...to.query, return_path: encodeURI(to.path) }, }; } else if ( to.meta.requiresDeveloperRole && !(userRepository.workflowDev || userRepository.admin) ) { return { name: "dashboard" }; } else if ( to.meta.requiresReviewerRole && !(userRepository.rewiewer || userRepository.admin) ) { return { name: "dashboard" }; } else if ( to.meta.requiresMaintainerRole && !(userRepository.resourceMaintainer || userRepository.admin) ) { return { name: "dashboard" }; } else if (to.meta.adminRole && !userRepository.admin) { return { name: "dashboard" }; } else if (to.name !== "login" && to.query.return_path) { // return to original path after login return { path: decodeURI(to.query.return_path as string) }; } }); nameRepository.loadNameMapping(); }); onMounted(() => { if (userRepository.authenticated) { resourceRepository.fetchPublicResources(); workflowRepository.fetchWorkflows(); bucketRepository.fetchBuckets(); s3KeyRepository.fetchS3Keys(); if (!userRepository.foreignUser) { bucketRepository.fetchOwnPermissions(); } if (userRepository.workflowDev || userRepository.admin) { workflowRepository.fetchOwnWorkflows(); } if (userRepository.resourceMaintainer || userRepository.admin) { resourceRepository.fetchOwnResources(); } } }); </script> <template> <AppHeader /> <div class="container-xxl mt-4 flex-grow-1 py-2"> <router-view></router-view> </div> <AppFooter /> </template> <style scoped></style>