162 lines
4.8 KiB
TypeScript
162 lines
4.8 KiB
TypeScript
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 reviveSession() {
|
|
return PersistentStorage.get<FG.Session>('fg_session').then((s) => fixSession(s || undefined));
|
|
}
|
|
|
|
function clearPersistant() {
|
|
void PersistentStorage.remove('fg_session');
|
|
}
|
|
|
|
export function saveSession(session?: FG.Session) {
|
|
if (session === undefined) return clearPersistant();
|
|
PersistentStorage.set('fg_session', session).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<FG_Plugin.Notification>,
|
|
shortcuts: [] as Array<FG_Plugin.MenuLink>,
|
|
}),
|
|
|
|
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;
|
|
},
|
|
currentSession(): FG.Session {
|
|
if (this.session === undefined) throw 'Not logged in, this should not be called';
|
|
return this.session;
|
|
},
|
|
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 {
|
|
this.session = await reviveSession();
|
|
if (this.session !== undefined) {
|
|
this.session = await sessionStore.getSession(this.session.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) {
|
|
const userStore = useUserStore();
|
|
try {
|
|
const { data } = await api.post<FG.Session>('/auth', { userid, password });
|
|
this.session = fixSession(data);
|
|
this.user = await userStore.getUser(data.userid, true);
|
|
return true;
|
|
} catch ({ response }) {
|
|
this.handleLoggedOut();
|
|
return (<AxiosResponse | undefined>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 ? (<AxiosResponse>response).status : false
|
|
);
|
|
},
|
|
|
|
async loadNotifications(flaschengeist: FG_Plugin.Flaschengeist) {
|
|
const { data } = await api.get<FG.Notification[]>('/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<Array<FG_Plugin.MenuLink>>(
|
|
`users/${this.currentUser.userid}/shortcuts`
|
|
);
|
|
this.shortcuts = data;
|
|
},
|
|
|
|
async setShortcuts() {
|
|
await api.put(`users/${this.currentUser.userid}/shortcuts`, this.shortcuts);
|
|
},
|
|
|
|
handleLoggedOut() {
|
|
this.$reset();
|
|
void clearPersistant();
|
|
},
|
|
},
|
|
});
|
|
|
|
export default () => useMainStore;
|