skillbox/client/src/main.js

167 lines
4.8 KiB
JavaScript

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),
});