diff --git a/src/boot/axios.ts b/src/boot/axios.ts index 2413f20..634bbe2 100644 --- a/src/boot/axios.ts +++ b/src/boot/axios.ts @@ -1,7 +1,8 @@ import axios, { AxiosInstance } from 'axios'; import { boot } from 'quasar/wrappers'; -import { Token, UserStateInterface } from 'src/plugins/user/store/user'; +import { UserStateInterface } from 'src/plugins/user/store/user'; import config from '../config'; +import { Store } from 'vuex'; declare module 'vue/types/vue' { interface Vue { @@ -9,18 +10,15 @@ declare module 'vue/types/vue' { } } -export default boot(({ Vue, store }) => { +export default boot>(({ Vue, store }) => { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access Vue.prototype.$axios = axios; axios.defaults.baseURL = config.baseURL; axios.interceptors.request.use(config => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment - const token: Token = store.getters['user/token']; - if (token) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - config.headers['Token'] = token.token; - //config.headers['Authorization'] = 'Token ' + token.token; + const session: Session = store.getters['user/session']; + if (session) { + config.headers['Authorization'] = 'Token ' + session.token; } return config; }); diff --git a/src/boot/login.ts b/src/boot/login.ts index 07103eb..94c8b49 100644 --- a/src/boot/login.ts +++ b/src/boot/login.ts @@ -1,41 +1,37 @@ import { boot } from 'quasar/wrappers'; -import { UserStateInterface } from 'src/plugins/user/store/user'; import { RouteRecord } from 'vue-router'; +import { Store } from 'vuex' +import { StateInterface } from 'src/store'; -export default boot(({ router, store }) => { +export default boot>(({ router, store }) => { router.beforeEach((to, from, next) => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access - store.dispatch('user/loadFromLocalStorage'); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/ban-ts-comment - // @ts-ignore - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - //const user: UserStateInterface = (store.state).user; - //const user: UserStateInterface = store.getters['user/user']; - const permissions: [] = store.getters['user/permissions']; - console.log('login_boot', permissions); - if ( - to.matched.some((record: RouteRecord) => { - // permissions is set AND has NO matching permission - return ( - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - record.meta.permissions !== undefined && - !( - // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access - ( - record.meta.permissions.filter((value: string) => - permissions.includes(value) - ).length > 0 + store.dispatch('user/loadFromLocalStorage').then(() => { + const permissions = store.getters['user/permissions']; + console.log('login_boot', permissions); + if ( + to.matched.some((record: RouteRecord) => { + // permissions is set AND has NO matching permission + return ( + permissions in record.meta && + !( + ( + record.meta.permissions.filter((value: string) => + permissions.includes(value) + ).length > 0 + ) ) - ) - ); - }) - ) { - next({ - path: '/login', - query: { redirect: to.fullPath } - }); - } else { - next(); - } - }); + ); + }) + ) { + next({ + path: '/login', + query: { redirect: to.fullPath } + }); + } else { + next(); + } + }).catch(error => { + console.exception(error); + }); + }) }); diff --git a/src/boot/plugins.ts b/src/boot/plugins.ts index f8bf787..6efdcc4 100644 --- a/src/boot/plugins.ts +++ b/src/boot/plugins.ts @@ -1,6 +1,7 @@ import { boot } from 'quasar/wrappers'; import { RouteConfig } from 'vue-router'; import { Module, Store } from 'vuex'; +import { StateInterface } from 'src/store'; const config = { // Do not change required Modules !! @@ -19,7 +20,7 @@ interface ShortCutLink { interface Plugin { name: string; routes: RouteConfig[]; - store?: Map>; + store?: Map>; mainLink: PluginMainLink; requiredModules: string[]; shortcuts: ShortCutLink[]; @@ -61,7 +62,7 @@ export { }; // combine routes from source to target -function combineRoutes( +function combineRoutes ( target: RouteConfig[], source: RouteConfig[] ): RouteConfig[] { @@ -74,15 +75,15 @@ function combineRoutes( ); if (targetRouteConfig) { // if exists first layer in target exist iterate through 2nd layer e.g. /main/user, /main/about - sourceRouteConfig.children?.forEach( + sourceRouteConfig.children ?.forEach( (sourcePluginChildRouteConfig: RouteConfig) => { const targetPluginRouteConfig: | RouteConfig - | undefined = targetRouteConfig.children?.find( - (routeConfig: RouteConfig) => { - return sourcePluginChildRouteConfig.path == routeConfig.path; - } - ); + | undefined = targetRouteConfig.children ?.find( + (routeConfig: RouteConfig) => { + return sourcePluginChildRouteConfig.path == routeConfig.path; + } + ); if (targetPluginRouteConfig) { // if 2nd layer in target exist check if target has children path. if (targetPluginRouteConfig.children) { @@ -113,7 +114,7 @@ function combineRoutes( } // combine Links of Plugins from source to target -function combineMainLinks( +function combineMainLinks ( target: PluginMainLink[], source: PluginMainLink ): PluginMainLink[] { @@ -134,7 +135,7 @@ function combineMainLinks( } // loade plugins -function loadPlugin( +function loadPlugin ( loadedPlugins: LoadedPlugins, modules: string[], plugins: Plugin[], @@ -180,7 +181,7 @@ function loadPlugin( // "async" is optional; // more info on params: https://quasar.dev/quasar-cli/cli-documentation/boot-files#Anatomy-of-a-boot-file -export default boot(({ Vue, router, store }) => { +export default boot>(({ Vue, router, store }) => { const plugins: Plugin[] = []; let loadedPlugins: LoadedPlugins = { routes: [], diff --git a/src/config.ts b/src/config.ts index 4e015ab..cdfcec4 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,5 +1,5 @@ const config = { - baseURL: "http://flaschengeist.local:5000" + baseURL: 'http://flaschengeist.local:5000' }; export default config; \ No newline at end of file diff --git a/src/flaschengeist.d.ts b/src/flaschengeist.d.ts new file mode 100644 index 0000000..a9b081c --- /dev/null +++ b/src/flaschengeist.d.ts @@ -0,0 +1,31 @@ +interface Session { + user: User; + expires: Date; + token: string; + lifetime: number; + browser: string; + platform: string; +} +interface User { + roles: Array; + userid: string; + display_name: string; + firstname: string; + lastname: string; + mail: string; +} +interface Permission { + id: number; + name: string; +} +interface Role { + permissions: Array; + id: number; + name: string; +} +interface UserAttribute { + id: number; + user: number; + name: string; + value: string; +} diff --git a/src/plugins/user/pages/Settings.vue b/src/plugins/user/pages/Settings.vue index ec49b8f..79c51b3 100644 --- a/src/plugins/user/pages/Settings.vue +++ b/src/plugins/user/pages/Settings.vue @@ -7,9 +7,7 @@
Deine Sessions:
-
+
Browser: - + {{ session.browser }}
Plattform: - + {{ session.platform }}
@@ -58,7 +62,10 @@
- +
@@ -103,7 +110,7 @@ export default defineComponent({ root.$store.dispatch('sessions/deleteSession', token); } function isThisSession(token: string) { - return root.$store.getters['user/token'].token == token; + return root.$store.getters['user/session'].token == token; } const sessionsLoading = computed(() => { diff --git a/src/plugins/user/pages/User.vue b/src/plugins/user/pages/User.vue index d59eb9d..55eb717 100644 --- a/src/plugins/user/pages/User.vue +++ b/src/plugins/user/pages/User.vue @@ -5,16 +5,22 @@ class="fit row justify-center content-center items-center" v-if="checkMain" > - + - Name: {{ userState.firstname }} {{ userState.lastname }}
- E-Mail: {{ userState.mail }}
+ Name: {{ userSession.user.firstname }} {{ userSession.user.lastname }}
+ E-Mail: {{ userSession.user.mail }}
Roles: -
    +
    • {{ role }}

    - Token expires: {{ userToken.expires }} + Token expires: {{ userSession.expires }} @@ -30,19 +36,16 @@ import { mainLink } from '../plugin'; export default defineComponent({ // name: 'PageName' setup(_, { root }) { - const userState = computed( - () => root.$store.getters['user/user'] - ); const userPermissions = computed( () => root.$store.getters['user/permissions'] ); - const userToken = computed( - () => root.$store.getters['user/token'] + const userSession = computed( + () => root.$store.getters['user/session'] ); const checkMain = computed(() => { return mainLink.name == root.$route.name; }); - return { userState, userPermissions, userToken, checkMain }; + return { userPermissions, userSession, checkMain }; } }); diff --git a/src/plugins/user/plugin.ts b/src/plugins/user/plugin.ts index ebfb36f..edd5a39 100644 --- a/src/plugins/user/plugin.ts +++ b/src/plugins/user/plugin.ts @@ -3,6 +3,7 @@ import { Module } from 'vuex'; import userStore from './store/user'; import sessionsStore from './store/session'; import routes from './routes'; +import { StateInterface } from 'src/store'; const mainLink: PluginMainLink = { name: 'user', @@ -27,7 +28,7 @@ const plugin: Plugin = { shortcutsOut: [], shortcuts: [], version: '0.0.1', - store: new Map>([ + store: new Map>([ ['user', userStore], ['sessions', sessionsStore] ]) diff --git a/src/plugins/user/store/session.ts b/src/plugins/user/store/session.ts index 257f390..98a6489 100644 --- a/src/plugins/user/store/session.ts +++ b/src/plugins/user/store/session.ts @@ -1,38 +1,29 @@ import { Module, MutationTree, ActionTree, GetterTree } from 'vuex'; import { StateInterface } from 'src/store'; -import { axios } from 'boot/axios'; -import { LoginData } from 'src/plugins/user/models'; -import { AxiosResponse } from 'axios'; -import { LocalStorage } from 'quasar'; -import { Router } from 'src/router'; +import { axios } from 'src/boot/axios'; + export interface SessionInterface { sessions: Session[]; loading: boolean; } -export interface Session { - browser: string; - expires: string; - lifetime: number; - platform: string; - token: string; -} + const state: SessionInterface = { sessions: [], loading: false }; const mutations: MutationTree = { - setSessions(state, sessions: Session[]) { + setSessions (state, sessions: Session[]) { state.sessions = sessions; }, - setLoading(state, value: boolean) { + setLoading (state, value: boolean) { state.loading = value; } }; const actions: ActionTree = { - getSessions({ commit, rootGetters }) { + getSessions ({ commit, rootGetters }) { console.log(rootGetters); commit('setLoading', true); axios @@ -48,7 +39,7 @@ const actions: ActionTree = { commit('setLoading', false); }); }, - deleteSession({ commit, dispatch, rootGetters }, token) { + deleteSession ({ commit, dispatch }, token: string) { commit('setLoading', true); console.log('axios', axios); axios @@ -57,7 +48,7 @@ const actions: ActionTree = { void dispatch('getSessions'); }) .catch(error => { - console.exception(); + console.exception(error); }) .finally(() => { commit('setLoading', false); @@ -66,10 +57,10 @@ const actions: ActionTree = { }; const getters: GetterTree = { - sessions(state) { + sessions (state) { return state.sessions; }, - loading(state) { + loading (state) { return state.loading; } }; diff --git a/src/plugins/user/store/user.ts b/src/plugins/user/store/user.ts index 78bfb95..f758945 100644 --- a/src/plugins/user/store/user.ts +++ b/src/plugins/user/store/user.ts @@ -6,69 +6,48 @@ import { AxiosResponse } from 'axios'; import { LocalStorage, Loading } from 'quasar'; import { Router } from 'src/router'; -export interface Token { - browser: string; - expires: string; - lifetime: number; - platform: string; - token: string; -} - -export interface User { - display_name: string | null; - firstname: string; - lastname: string; - mail: string; - roles: string[]; - userid: string; -} - export interface UserStateInterface extends LoginResponse { loginLoading: boolean; } export interface LoginResponse { permissions: string[]; - token: Token; - user: User; - userid: string; + session: Session; } const state: UserStateInterface = { permissions: [], - token: { browser: '', expires: '', lifetime: -1, platform: '', token: '' }, - user: { - display_name: '', - firstname: '', - lastname: '', - mail: '', - roles: [], - userid: '' + session: { + browser: '', expires: new Date(), lifetime: -1, platform: '', token: '', + user: { + display_name: '', + firstname: '', + lastname: '', + mail: '', + roles: [], + userid: '' + } }, loginLoading: false }; const mutations: MutationTree = { - setPermissions(state, data: []) { + setPermissions (state, data: []) { state.permissions = data; }, - setToken(state, data: Token) { - state.token = data; + setSession (state, data: Session) { + state.session = data; }, - setUser(state, data: User) { - state.user = data; - }, - setLoginLoading(state, data: boolean) { + setLoginLoading (state, data: boolean) { state.loginLoading = data; }, - showState(state) { + showState (state) { console.log(state); } }; const actions: ActionTree = { - login({ commit }, data: LoginData) { - console.log('bla'); + login ({ commit }, data: LoginData) { commit('setLoginLoading', true); Loading.show({ message: 'Du wirst eingeloggt' }); void axios @@ -76,12 +55,10 @@ const actions: ActionTree = { .then((response: AxiosResponse) => { commit('setPermissions', response.data.permissions); console.log('saved permisisons'); - commit('setToken', response.data.token); - commit('setUser', response.data.user); + commit('setSession', response.data.session); commit('showState'); LocalStorage.set('permissions', response.data.permissions); - LocalStorage.set('token', response.data.token); - LocalStorage.set('user', response.data.user); + LocalStorage.set('session', response.data.session); void Router.push({ name: 'user' }); }) @@ -93,46 +70,29 @@ const actions: ActionTree = { Loading.hide(); }); }, - loadFromLocalStorage({ commit }) { + loadFromLocalStorage ({ commit }) { console.log('load from store'); let data = LocalStorage.getItem('permissions'); commit('setPermissions', data ? data : []); - data = LocalStorage.getItem('token'); + data = LocalStorage.getItem('session'); commit( - 'setToken', + 'setSession', data ? data - : { browser: '', expires: '', lifetime: -1, platform: '', token: '' } - ); - data = LocalStorage.getItem('user'); - commit( - 'setUser', - data - ? data - : { - display_name: '', - firstname: '', - lastname: '', - mail: '', - roles: [], - userid: '' - } + : { browser: '', expires: new Date(), lifetime: -1, platform: '', token: '' } ); commit('showState'); } }; const getters: GetterTree = { - permissions({ permissions }) { + permissions ({ permissions }) { return permissions; }, - token({ token }) { - return token; + session ({ session }) { + return session; }, - user({ user }) { - return user; - }, - loginLoading({ loginLoading }) { + loginLoading ({ loginLoading }) { return loginLoading; } }; diff --git a/src/router/index.ts b/src/router/index.ts index b70714d..e1b75f9 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,8 +1,8 @@ import { route } from 'quasar/wrappers'; import VueRouter from 'vue-router'; import { Store } from 'vuex'; -import { StateInterface } from '../store'; import routes from './routes'; +import { StateInterface } from 'src/store'; /* * If not building with SSR mode, you can @@ -19,7 +19,7 @@ export const Router: VueRouter = new VueRouter({ base: process.env.VUE_ROUTER_BASE }); -export default route>(function({ Vue }) { +export default route>(function ({ Vue }) { Vue.use(VueRouter); return Router; diff --git a/src/store/index.ts b/src/store/index.ts index 893c2ba..a71b4b2 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,20 +1,16 @@ import { store } from 'quasar/wrappers'; import Vuex from 'vuex'; -import user from './module-user'; -import { UserStateInterface } from './module-user/state'; - /* * If not building with SSR mode, you can * directly export the Store instantiation */ - export interface StateInterface { - // Define your own store structure, using submodules if needed - example: unknown; + } -export default store(function({ Vue }) { + +export default store(function ({ Vue }) { Vue.use(Vuex); const Store = new Vuex.Store({