import { create } from "zustand"; import type { User } from "../lib/api"; const TOKEN_KEY = "pm_token"; const USER_KEY = "pm_user"; /** نشست ERP روی همین دامنه (zustand persist) — منبع تک‌احراز هویت مجموعه */ const ERP_SESSION_KEY = "procurement-auth-v1"; function readErpToken(): string | null { try { const raw = localStorage.getItem(ERP_SESSION_KEY); if (!raw) return null; const parsed = JSON.parse(raw) as { state?: { token?: string | null } }; return parsed.state?.token ?? null; } catch { return null; } } function readToken(): string | null { try { const legacy = localStorage.getItem(TOKEN_KEY); if (legacy) return legacy; // SSO — توکن Casdoorِ نشست ERP همان نشست PM است return readErpToken(); } catch { return null; } } interface AuthState { token: string | null; user: User | null; setAuth: (token: string, user: User) => void; /** به‌روزرسانی کاربر جاری (بعد از تغییر نقش/دسترسی‌ها یا خواندن /auth/me) */ setUser: (user: User) => void; clear: () => void; } function readErpUser(): User | null { try { const raw = localStorage.getItem(ERP_SESSION_KEY); if (!raw) return null; const parsed = JSON.parse(raw) as { state?: { user?: { first_name?: string; last_name?: string; display_name?: string; username?: string; casdoor_id?: string; role?: string; role_label?: string; } | null; }; }; const eu = parsed.state?.user; if (!eu) return null; const role: import("../lib/api").Role = eu.role === "supervisor" ? "project_supervisor" : "project_manager"; return { id: eu.username || eu.casdoor_id || "sso", username: eu.username || eu.casdoor_id || "user", display_name: eu.display_name || `${eu.first_name || ""} ${eu.last_name || ""}`.trim() || eu.username || "کاربر", role, role_label: eu.role_label || (role === "project_supervisor" ? "سرپرست پروژه" : "مدیر پروژه"), permissions: [], scope: { all_projects: role === "project_manager", project_count: null }, }; } catch { return null; } } function readUser(): User | null { try { const erpUser = readErpUser(); const raw = localStorage.getItem(USER_KEY); if (raw) { const pmUser = JSON.parse(raw) as User; if (erpUser && (pmUser.username !== erpUser.username || pmUser.role !== erpUser.role)) { localStorage.removeItem(USER_KEY); return erpUser; } return pmUser; } return erpUser; } catch { return null; } } function writeUser(user: User | null): void { try { if (user) localStorage.setItem(USER_KEY, JSON.stringify(user)); else localStorage.removeItem(USER_KEY); } catch { /* حافظه در دسترس نیست */ } } /** وضعیت احراز هویت — توکن در localStorage نگه‌داری می‌شود */ export const useAuthStore = create()((set) => ({ token: readToken(), user: readUser(), setAuth: (token, user) => { try { localStorage.setItem(TOKEN_KEY, token); } catch { /* حافظه در دسترس نیست */ } writeUser(user); set({ token, user }); }, setUser: (user) => { writeUser(user); set({ user }); }, clear: () => { try { localStorage.removeItem(TOKEN_KEY); } catch { /* حافظه در دسترس نیست */ } writeUser(null); set({ token: null, user: null }); }, })); /** آیا نشست ذخیره‌شده اطلاعات نقش را دارد؟ (نشست‌های پیش از RBAC ندارند) */ export function sessionNeedsRefresh(user: User | null): boolean { return !user || !user.role || !Array.isArray(user.permissions); }