Squashed 'pm/' content from commit 91f3271
git-subtree-dir: pm git-subtree-split: 91f3271d866fa8ee471cfb6793e334b83e6d2b6e
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
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<AuthState>()((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);
|
||||
}
|
||||
Reference in New Issue
Block a user