import '@babel/polyfill'; import Vue from 'vue'; import VueVimeoPlayer from 'vue-vimeo-player'; import apolloClientFactory from './graphql/client'; import VueApollo from 'vue-apollo'; import App from './App'; import {postLoginRedirectUrlKey, router} from './router'; import store from '@/store/index'; import VueScrollTo from 'vue-scrollto'; import autoGrow from '@/directives/auto-grow'; import clickOutside from '@/directives/click-outside'; import ME_QUERY from '@/graphql/gql/queries/meQuery.gql'; import VueModal from '@/plugins/modal'; import VueRemoveEdges from '@/plugins/edges'; import VueMatomo from 'vue-matomo'; import VueToast from 'vue-toast-notification'; import VueLogger from 'vuejs-logger'; Vue.config.productionTip = false; const isProduction = process.env.NODE_ENV === 'production'; Vue.use(VueModal); Vue.use(VueRemoveEdges); Vue.use(VueApollo); Vue.use(VueVimeoPlayer); Vue.use(VueToast); Vue.use(VueLogger, { isEnabled: true, logLevel: isProduction ? 'error' : 'debug', stringifyArguments: false, showConsoleColors: true, }); Vue.use(VueScrollTo, { duration: 500, easing: 'ease-out', offset: -50, }); if (process.env.MATOMO_HOST) { Vue.use(VueMatomo, { host: process.env.MATOMO_HOST, siteId: process.env.MATOMO_SITE_ID, router: router, }); } Vue.directive('click-outside', clickOutside); Vue.directive('auto-grow', autoGrow); const publicApolloClient = apolloClientFactory('/api/graphql-public/', null); const privateApolloClient = apolloClientFactory('/api/graphql/', networkErrorCallback); const apolloProvider = new VueApollo({ clients: { publicClient: publicApolloClient, }, defaultClient: privateApolloClient, }); /* guards */ function getCookieValue(cookieName) { // https://stackoverflow.com/questions/5639346/what-is-the-shortest-function-for-reading-a-cookie-by-name-in-javascript let cookieValue = document.cookie.match('(^|[^;]+)\\s*' + cookieName + '\\s*=\\s*([^;]+)'); return cookieValue ? cookieValue.pop() : ''; } function loginRequired(to) { // public pages have the meta.public property set to true return !Object.prototype.hasOwnProperty.call(to, 'meta') || !Object.prototype.hasOwnProperty.call(to.meta ,'public') || !to.meta.public; } function unauthorizedAccess(to) { return loginRequired(to) && getCookieValue('loginStatus') !== 'true'; } function redirectUsersWithoutValidLicense() { return privateApolloClient.query({ query: ME_QUERY, }).then(({data}) => data.me.expiryDate == null); } function redirectStudentsWithoutClass() { return privateApolloClient.query({ query: ME_QUERY, }).then(({data}) => data.me.schoolClasses.length === 0 && !data.me.isTeacher); } function redirectUsersToOnboarding() { return privateApolloClient.query({ query: ME_QUERY, }).then(({data}) => !data.me.onboardingVisited); } function networkErrorCallback(statusCode) { if (statusCode === 402) { Vue.$log.debug('status code 402, redirecting'); router.push({name: 'licenseActivation'}, 0); } } function joiningClass(to) { return to.name && (to.name === 'join-class' || to.name === 'licenseActivation'); } router.beforeEach(async (to, from, next) => { Vue.$log.debug('navigation guard called', to, from); if (to.path === '/logout') { publicApolloClient.resetStore(); if (process.env.LOGOUT_REDIRECT_URL) { location.replace(`https://sso.hep-verlag.ch/logout?return_to=${process.env.LOGOUT_REDIRECT_URL}`); next(false); return; } else { next({name: 'hello'}); return; } } if (unauthorizedAccess(to)) { Vue.$log.debug('unauthorized', to); const postLoginRedirectionUrl = to.path; const redirectUrl = `/hello/`; if (window.localStorage) { localStorage.setItem(postLoginRedirectUrlKey, postLoginRedirectionUrl); } Vue.$log.debug('redirecting to hello', to); next(redirectUrl); return; } if (to.name && to.name !== 'licenseActivation' && loginRequired(to) && await redirectUsersWithoutValidLicense()) { Vue.$log.debug('redirecting to licenseActivation', to, null); console.log('redirecting to licenseActivation', to, null); next({name: 'licenseActivation'}); return; } if (!joiningClass(to) && loginRequired(to) && await redirectStudentsWithoutClass()) { Vue.$log.debug('redirecting to join-class', to); Vue.$log.debug('await redirectStudentsWithoutClass()', await redirectStudentsWithoutClass()); next({name: 'join-class'}); return; } if ((to.name && to.name.indexOf('onboarding') === -1) && !joiningClass(to) && loginRequired(to) && await redirectUsersToOnboarding()) { Vue.$log.debug('redirecting to onboarding-start', to); next({name: 'onboarding-start'}); return; } Vue.$log.debug('End of Guard reached', to); next(); }); /* eslint-disable no-new */ new Vue({ el: '#app', store, router, apolloProvider, render: h => h(App), });