import { FG_Plugin } from '@flaschengeist/types'; import { fixSession, useSessionStore, useUserStore } from '.'; import { AxiosResponse } from 'axios'; import { api } from '../internal'; import { defineStore } from 'pinia'; import { PersistentStorage } from '../utils/persistent'; function loadToken() { return PersistentStorage.get('fg_token'); } function clearToken() { void PersistentStorage.remove('fg_token'); } export function saveToken(token?: string) { if (token === undefined) return clearToken(); PersistentStorage.set('fg_token', token).catch(() => console.error('Could not save token to storage') ); } export const useMainStore = defineStore({ id: 'main', state: () => ({ session: undefined as FG.Session | undefined, user: undefined as FG.User | undefined, notifications: [] as Array, shortcuts: [] as Array, }), getters: { loggedIn(): boolean { return this.session !== undefined; }, currentUser(): FG.User { if (this.user === undefined) throw 'Not logged in, this should not be called'; return this.user; }, permissions(): string[] { return this.user?.permissions || []; }, }, actions: { /** Ininitalize store from saved session * Updates session and loads current user */ async init() { const sessionStore = useSessionStore(); const userStore = useUserStore(); try { const token = await loadToken(); if (token !== null) { this.session = await sessionStore.getSession(token); if (this.session !== undefined) this.user = await userStore.getUser(this.session.userid); } } catch (error) { console.warn('Could not load token from storage', error); } }, async login(userid: string, password: string) { try { const { data } = await api.post('/auth', { userid, password }); this.session = fixSession(data); return true; } catch ({ response }) { return (response)?.status || false; } }, async logout() { if (!this.session || !this.session.token) return false; try { const token = this.session.token; await api.delete(`/auth/${token}`); } catch (error) { return false; } finally { this.handleLoggedOut(); } 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(flaschengeist: FG_Plugin.Flaschengeist) { const { data } = await api.get('/notifications', { params: this.notifications.length > 0 ? { from: this.notifications[this.notifications.length - 1].time } : {}, }); const notes = [] as FG_Plugin.Notification[]; data.forEach((n) => { n.time = new Date(n.time); const plugin = flaschengeist?.plugins.filter((p) => p.id === n.plugin)[0]; if (!plugin) console.debug('Could not find a parser for this notification', n); else notes.push(plugin.notification(n)); }); this.notifications.push(...notes); return notes; }, 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); } }, async getShortcuts() { const { data } = await api.get>( `users/${this.currentUser.userid}/shortcuts` ); this.shortcuts = data; }, async setShortcuts() { await api.put(`users/${this.currentUser.userid}/shortcuts`, this.shortcuts); }, handleLoggedOut() { this.$reset(); void clearToken(); }, }, }); export default () => useMainStore;