import { store } from 'quasar/wrappers'; import { createStore } from 'vuex'; export interface StateInterface { [key: string]: unknown; } export default store(function (/* { ssrContext } */) { const Store = createStore({ modules: {}, // enable strict mode (adds overhead!) // for dev mode and --debug builds only strict: !!process.env.DEBUGGING, }); return Store; }); import { defineStore } from 'pinia'; import { api } from 'src/boot/axios'; import { AxiosResponse } from 'axios'; import { LocalStorage, SessionStorage } from 'quasar'; import { useUserStore, useSessionStore } from 'src/plugins/user/store'; function loadCurrentSession() { const session = LocalStorage.getItem('session'); if (session) session.expires = new Date(session.expires); return session || undefined; } function loadUser() { const user = SessionStorage.getItem('user'); if (user && user.birthday) user.birthday = new Date(user.birthday); return user || undefined; } export const useMainStore = defineStore({ id: 'main', state: () => ({ session: loadCurrentSession(), user: loadUser(), notifications: [] as Array, }), getters: { loggedIn() { return this.session !== undefined; }, currentUser() { if (this.user === undefined) throw 'Not logged in, this should not be called'; return this.user; }, permissions() { return this.user?.permissions || []; }, }, actions: { /** Ininitalize store from saved session * Updates session and loads current user */ async init() { if (this.session) { const sessionStore = useSessionStore(); const session = await sessionStore.getSession(this.session.token); if (session) { this.session = this.session; const userStore = useUserStore(); const user = await userStore.getUser(this.session.userid); if (user) { this.user = user; SessionStorage.set('user', user); } } } }, async login(userid: string, password: string) { try { const { data } = await api.post('/auth', { userid, password }); this.session = data; this.session.expires = new Date(this.session.expires); LocalStorage.set('session', this.session); return true; } catch ({ response }) { return (response)?.status || false; } }, async logout() { if (!this.session || !this.session.token) return false; LocalStorage.clear(); try { const token = this.session.token; this.$patch({ session: undefined, user: undefined, }); await api.delete(`/auth/${token}`); } catch (error) { return false; } finally { SessionStorage.clear(); } return true; }, async requestReset(userid: string) { return await api .post('/auth/reset', { userid }) .then(() => true) .catch(() => false); }, async resetPassword(token: string, password: string) { return await api .post('/auth/reset', { token, password }) .then(() => true) .catch(({ response }) => response && 'status' in response ? (response).status : false ); }, async loadNotifications() { const params = this.notifications.length > 0 ? { from: this.notifications[this.notifications.length - 1].time } : {}; const { data } = await api.get('/notifications', { params: params }); data.forEach((n) => { n.time = new Date(n.time); if (window.Notification.permission === 'granted') new window.Notification(n.text, { timestamp: n.time.getTime(), }); }); this.notifications.push(...data); }, async removeNotification(id: number) { const idx = this.notifications.findIndex((n) => n.id === id); if (idx >= 0) try { this.notifications.splice(idx, 1); await api.delete(`/notifications/${id}`); } catch (error) { if (this.notifications.length > idx) this.notifications.splice(idx, this.notifications.length - idx - 1); } }, }, });