skillbox/client/src/main.js

152 lines
4.1 KiB
JavaScript

import '@babel/polyfill'
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
import VueVimeoPlayer from 'vue-vimeo-player'
import apolloClientFactory from './graphql/client'
import VueApollo from 'vue-apollo'
import App from './App'
import router from './router'
import store from '@/store/index'
import VueScrollTo from 'vue-scrollto';
import {Validator, install as VeeValidate} from 'vee-validate/dist/vee-validate.minimal.esm.js';
import {required, min} from 'vee-validate/dist/rules.esm.js';
import veeDe from 'vee-validate/dist/locale/de';
import {dateFilter} from './filters/date-filter';
import autoGrow from '@/directives/auto-grow'
import clickOutside from '@/directives/click-outside'
import ME_QUERY from '@/graphql/gql/meQuery.gql';
import VueModal from '@/plugins/modal';
import VueRemoveEdges from '@/plugins/edges';
import VueMatomo from 'vue-matomo'
Vue.config.productionTip = false;
Vue.use(VueModal);
Vue.use(VueRemoveEdges);
Vue.use(VueApollo);
Vue.use(VueAxios, axios);
Vue.use(VueVimeoPlayer);
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/');
const privateApolloClient = apolloClientFactory('/api/graphql/');
const apolloProvider = new VueApollo({
clients: {
publicClient: publicApolloClient
},
defaultClient: privateApolloClient
});
Validator.extend('required', required);
Validator.extend('min', min);
const dict = {
custom: {
oldPassword: {
required: 'Dein aktuelles Passwort fehlt'
},
newPassword: {
required: 'Dein neues Passwort fehlt',
min: 'Das neue Passwort muss mindestens 8 Zeichen lang sein'
}
}
};
Validator.localize('de', veeDe)
Validator.localize('de', dict)
// https://github.com/baianat/vee-validate/issues/51
Validator.extend('strongPassword', {
getMessage: field => 'Das Passwort muss Grossbuchstaben, Zahlen und Sonderzeichen beinhalten',
validate: value => {
const strongRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*?(),.":{}|<>+])(?=.{8,})/;
return strongRegex.test(value);
}
});
Validator.extend('email', {
getMessage: field => 'Bitte geben Sie eine gülitge E-Mail an',
validate: value => {
const emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/;
return emailRegex.test(value);
}
});
Vue.use(VeeValidate, {
locale: 'de'
});
Vue.filter('date', dateFilter);
/* 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 !to.hasOwnProperty('meta') || !to.meta.hasOwnProperty('public') || !to.meta.public;
}
function unauthorizedAccess(to) {
return loginRequired(to) && getCookieValue('loginStatus') !== 'true';
}
function redirectStudentsWithoutClass() {
return privateApolloClient.query({
query: ME_QUERY,
}).then(({data}) => data.me.schoolClasses.edges.length === 0 && data.me.permissions.length === 0);
}
router.beforeEach(async (to, from, next) => {
// handle logout
if (to.path === '/logout') {
privateApolloClient.resetStore();
publicApolloClient.resetStore();
next({name: 'login'});
return
}
if (unauthorizedAccess(to)) {
const redirectUrl = `/login?redirect=${to.path}`;
next(redirectUrl);
return
}
if (to.name !== 'join-class' && loginRequired(to) && await redirectStudentsWithoutClass()) {
next({name: 'join-class'})
return
}
next();
});
/* eslint-disable no-new */
new Vue({
el: '#app',
store,
router,
provide: apolloProvider.provide(),
render: h => h(App)
});