Logging out or switching accounts kept the previous user's React Query cache (follows, feed, cloud, e621 pages), so the new account briefly saw the old one's followed tags/pools until each query refetched. The query client now lives in lib/queryClient.ts and login/register/logout clear it alongside the e621 credential store.
71 lines
1.9 KiB
TypeScript
71 lines
1.9 KiB
TypeScript
import { create } from "zustand";
|
|
|
|
import { api, getToken, setToken } from "@/lib/api";
|
|
import { queryClient } from "@/lib/queryClient";
|
|
import type { User } from "@/lib/types";
|
|
import { useE621 } from "@/store/e621";
|
|
|
|
interface AuthState {
|
|
user: User | null;
|
|
ready: boolean;
|
|
login: (username: string, password: string) => Promise<void>;
|
|
register: (username: string, password: string) => Promise<void>;
|
|
logout: () => Promise<void>;
|
|
loadUser: () => Promise<void>;
|
|
}
|
|
|
|
export const useAuth = create<AuthState>((set) => ({
|
|
user: null,
|
|
ready: false,
|
|
|
|
login: async (username, password) => {
|
|
const data = await api<{ token: string }>("/api/auth/token/", {
|
|
method: "POST",
|
|
json: { username, password },
|
|
});
|
|
setToken(data.token);
|
|
const user = await api<User>("/api/auth/me/");
|
|
// Never show the previous account's cached data to this one.
|
|
queryClient.clear();
|
|
useE621.getState().clear();
|
|
set({ user, ready: true });
|
|
},
|
|
|
|
register: async (username, password) => {
|
|
const data = await api<{ token: string; user: User }>("/api/auth/register/", {
|
|
method: "POST",
|
|
json: { username, password },
|
|
});
|
|
setToken(data.token);
|
|
queryClient.clear();
|
|
useE621.getState().clear();
|
|
set({ user: data.user, ready: true });
|
|
},
|
|
|
|
logout: async () => {
|
|
try {
|
|
await api("/api/auth/logout/", { method: "POST" });
|
|
} catch {
|
|
// The token may already be invalid; clearing it locally is enough.
|
|
}
|
|
setToken(null);
|
|
queryClient.clear();
|
|
useE621.getState().clear();
|
|
set({ user: null, ready: true });
|
|
},
|
|
|
|
loadUser: async () => {
|
|
if (!getToken()) {
|
|
set({ user: null, ready: true });
|
|
return;
|
|
}
|
|
try {
|
|
const user = await api<User>("/api/auth/me/");
|
|
set({ user, ready: true });
|
|
} catch {
|
|
setToken(null);
|
|
set({ user: null, ready: true });
|
|
}
|
|
},
|
|
}));
|