70 lines
2.1 KiB
TypeScript
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 });
|
|
}
|
|
}));
|