61 lines
1.6 KiB
TypeScript
61 lines
1.6 KiB
TypeScript
import { defineStore } from 'pinia';
|
|
import { User } from '../interfaces/user.interfaces';
|
|
import { useLocalStorage } from '@vueuse/core';
|
|
import jwtDecode from 'jwt-decode';
|
|
import { BACKEND_URL } from '../constants';
|
|
import jfetch from '../utils/jfetch';
|
|
|
|
export const useUserStore = defineStore('user', {
|
|
state: () => {
|
|
return {
|
|
currentUser: null as User | null,
|
|
accessToken: useLocalStorage<string>('accessToken', null, {
|
|
writeDefaults: false,
|
|
}),
|
|
};
|
|
},
|
|
getters: {
|
|
user: (state) => state.currentUser!,
|
|
isLoggedIn: (state) => !!state.currentUser,
|
|
},
|
|
actions: {
|
|
loginFromToken() {
|
|
const token = this.accessToken;
|
|
try {
|
|
const decoded = jwtDecode(token) as Record<string, unknown>;
|
|
if (!decoded.sub) {
|
|
throw new Error('Invalid token');
|
|
}
|
|
this.currentUser = {
|
|
sub: decoded.sub as string,
|
|
name: decoded.name as string,
|
|
email: decoded.email as string,
|
|
picture: decoded.picture as string,
|
|
};
|
|
} catch {
|
|
// TODO
|
|
}
|
|
},
|
|
async login({ email, password }: { email: string; password: string }) {
|
|
const header = btoa(`${email}:${password}`);
|
|
const { data: tokenResponse } = await jfetch(
|
|
`${BACKEND_URL}/user/login`,
|
|
{
|
|
method: 'POST',
|
|
headers: new Headers({
|
|
Authorization: `Basic ${header}`,
|
|
'Content-Type': 'application/json',
|
|
}),
|
|
}
|
|
);
|
|
|
|
this.accessToken = tokenResponse.access_token;
|
|
this.loginFromToken();
|
|
},
|
|
logout() {
|
|
this.accessToken = '';
|
|
this.currentUser = null;
|
|
},
|
|
},
|
|
});
|