'use client'; import { create } from 'zustand'; import type { Member } from '@/lib/members'; import { ensureMemberUsernames } from '@/lib/members'; import { SYSTEM_ADMIN_MEMBER, ensureSystemAdminMember } from '@/lib/member-system'; import { findMemberByUsernameCredentials, resolveAuthUserFromMembers, toAuthUser, type AuthUser } from '@/lib/auth-user'; import { listMembersDomain } from '@/lib/domain-api'; import { useMemberStore } from './useMemberStore'; interface AuthState { user: AuthUser | null; isAuthenticated: boolean; login: (username: string, password: string, remember: boolean) => Promise; logout: () => void; checkAuth: () => void; refreshUser: () => Promise; } const SESSION_KEY = 'ftb_auth_session'; const PERSIST_KEY = 'ftb_auth_persist'; const FALLBACK_MEMBERS: Member[] = [SYSTEM_ADMIN_MEMBER]; function writeAuthStorage(user: AuthUser, remember: boolean) { sessionStorage.setItem(SESSION_KEY, JSON.stringify(user)); if (remember) { localStorage.setItem(PERSIST_KEY, JSON.stringify(user)); } } function clearAuthStorage() { sessionStorage.removeItem(SESSION_KEY); localStorage.removeItem(PERSIST_KEY); } async function loadMembersForAuth(): Promise { try { const domainMembers = await listMembersDomain(); if (domainMembers.length) { const ensured = ensureSystemAdminMember(domainMembers); return ensureMemberUsernames(ensured.members).members; } } catch {} const inMemoryMembers = useMemberStore.getState().members; const members = inMemoryMembers.length > 0 ? ensureSystemAdminMember(inMemoryMembers).members : FALLBACK_MEMBERS; return ensureMemberUsernames(members).members; } async function refreshStoredAuthUser(user: AuthUser, remember: boolean, set: (state: Partial) => void) { try { const members = await loadMembersForAuth(); const next = resolveAuthUserFromMembers(user, members); if (!next) { clearAuthStorage(); set({ user: null, isAuthenticated: false }); return; } set({ user: next, isAuthenticated: true }); writeAuthStorage(next, remember); } catch {} } export const useAuthStore = create((set) => ({ user: null, isAuthenticated: false, login: async (username, password, remember) => { const members = await loadMembersForAuth(); const member = findMemberByUsernameCredentials(username, password, members); if (!member) return false; const user = toAuthUser(member); set({ user, isAuthenticated: true }); writeAuthStorage(user, remember); return true; }, logout: () => { set({ user: null, isAuthenticated: false }); clearAuthStorage(); }, checkAuth: () => { const session = sessionStorage.getItem(SESSION_KEY); if (session) { const user = JSON.parse(session); set({ user, isAuthenticated: true }); void refreshStoredAuthUser(user, !!localStorage.getItem(PERSIST_KEY), set); return; } const persist = localStorage.getItem(PERSIST_KEY); if (persist) { const user = JSON.parse(persist); set({ user, isAuthenticated: true }); writeAuthStorage(user, true); void refreshStoredAuthUser(user, true, set); return; } }, refreshUser: async () => { const cur = useAuthStore.getState().user; if (!cur) return; try { const memoryMember = useMemberStore.getState().members.find((x) => x.id === cur.id); const members = memoryMember ? [memoryMember] : await loadMembersForAuth(); const member = members.find((x) => x.id === cur.id); if (!member) return; const next = toAuthUser(member); useAuthStore.setState({ user: next }); writeAuthStorage(next, !!localStorage.getItem(PERSIST_KEY)); } catch {} }, }));