Some checks failed
E2E / Playwright e2e (push) Has been cancelled
Move mail, compose, contacts, and accounts off mocks onto REST + WS. Add client, auth store, IDB-backed query cache, offline queue, and sync bar; hybrid Zustand for UI-only state. Settings still local until backend has preferences API.
43 lines
1.2 KiB
TypeScript
43 lines
1.2 KiB
TypeScript
"use client"
|
|
|
|
import { create } from "zustand"
|
|
import { persist } from "zustand/middleware"
|
|
import { debouncedPersistJSONStorage } from "@/lib/stores/debounced-json-storage"
|
|
|
|
interface AuthState {
|
|
accessToken: string | null
|
|
refreshToken: string | null
|
|
expiresAt: number | null
|
|
login: (accessToken: string, refreshToken: string, expiresAt: number) => void
|
|
logout: () => void
|
|
isAuthenticated: () => boolean
|
|
}
|
|
|
|
export const useAuthStore = create<AuthState>()(
|
|
persist(
|
|
(set, get) => ({
|
|
accessToken: null,
|
|
refreshToken: null,
|
|
expiresAt: null,
|
|
login: (accessToken, refreshToken, expiresAt) =>
|
|
set({ accessToken, refreshToken, expiresAt }),
|
|
logout: () =>
|
|
set({ accessToken: null, refreshToken: null, expiresAt: null }),
|
|
isAuthenticated: () => {
|
|
const { accessToken, expiresAt } = get()
|
|
if (!accessToken || !expiresAt) return false
|
|
return Date.now() < expiresAt
|
|
},
|
|
}),
|
|
{
|
|
name: "ultimail-auth",
|
|
storage: debouncedPersistJSONStorage,
|
|
partialize: (state) => ({
|
|
accessToken: state.accessToken,
|
|
refreshToken: state.refreshToken,
|
|
expiresAt: state.expiresAt,
|
|
}),
|
|
}
|
|
)
|
|
)
|