Files
Messenger/web/src/store/authStore.ts

70 lines
2.1 KiB
TypeScript

import { create } from "zustand";
import { loginRequest, meRequest, refreshRequest } from "../api/auth";
import type { AuthUser } from "../chat/types";
import { unregisterWebPushToken } from "../utils/firebasePush";
import { useChatStore } from "./chatStore";
interface AuthState {
accessToken: string | null;
refreshToken: string | null;
me: AuthUser | null;
loading: boolean;
setTokens: (accessToken: string, refreshToken: string) => void;
login: (email: string, password: string, otpCode?: string, recoveryCode?: string) => Promise<void>;
loadMe: () => Promise<void>;
refresh: () => Promise<void>;
logout: () => void;
}
const ACCESS_KEY = "bm_access_token";
const REFRESH_KEY = "bm_refresh_token";
export const useAuthStore = create<AuthState>((set, get) => ({
accessToken: localStorage.getItem(ACCESS_KEY),
refreshToken: localStorage.getItem(REFRESH_KEY),
me: null,
loading: false,
setTokens: (accessToken, refreshToken) => {
localStorage.setItem(ACCESS_KEY, accessToken);
localStorage.setItem(REFRESH_KEY, refreshToken);
set({ accessToken, refreshToken, me: null });
},
login: async (email, password, otpCode, recoveryCode) => {
set({ loading: true });
try {
const data = await loginRequest(email, password, otpCode, recoveryCode);
get().setTokens(data.access_token, data.refresh_token);
await get().loadMe();
} finally {
set({ loading: false });
}
},
loadMe: async () => {
const tokenAtStart = get().accessToken;
if (!tokenAtStart) {
set({ me: null });
return;
}
const me = await meRequest();
if (get().accessToken === tokenAtStart) {
set({ me });
}
},
refresh: async () => {
const token = get().refreshToken;
if (!token) {
get().logout();
return;
}
const data = await refreshRequest(token);
get().setTokens(data.access_token, data.refresh_token);
},
logout: () => {
void unregisterWebPushToken();
localStorage.removeItem(ACCESS_KEY);
localStorage.removeItem(REFRESH_KEY);
useChatStore.getState().reset();
set({ accessToken: null, refreshToken: null, me: null });
}
}));