88 lines
2.4 KiB
TypeScript
88 lines
2.4 KiB
TypeScript
import { create } from "zustand";
|
|
import { UserProfile } from "@/types/api";
|
|
import { usePermissionStore } from "./permissionStore";
|
|
|
|
export type AuthState = {
|
|
accessToken?: string;
|
|
refreshToken?: string;
|
|
tokenType?: string;
|
|
expiresInSeconds?: number;
|
|
tenantId?: string;
|
|
profile?: UserProfile;
|
|
};
|
|
|
|
type AuthAction = {
|
|
setAuthFromLogin: (payload: {
|
|
tokenType: string;
|
|
accessToken: string;
|
|
refreshToken: string;
|
|
expiresInSeconds: number;
|
|
}) => void;
|
|
setProfile: (profile: UserProfile) => void;
|
|
setTenantId: (tenantId: string) => void;
|
|
clearAuth: () => void;
|
|
hydrate: () => void;
|
|
};
|
|
|
|
const STORAGE_KEY = "utms-ng-auth";
|
|
|
|
export const useAuthStore = create<AuthState & AuthAction>((set, get) => ({
|
|
accessToken: undefined,
|
|
refreshToken: undefined,
|
|
tokenType: undefined,
|
|
expiresInSeconds: undefined,
|
|
tenantId: process.env.NEXT_PUBLIC_DEFAULT_TENANT,
|
|
profile: undefined,
|
|
setAuthFromLogin: ({ tokenType, accessToken, refreshToken, expiresInSeconds }) => {
|
|
const tenantId = get().tenantId || process.env.NEXT_PUBLIC_DEFAULT_TENANT || "acme";
|
|
const next = {
|
|
tokenType,
|
|
accessToken,
|
|
refreshToken,
|
|
expiresInSeconds,
|
|
tenantId
|
|
};
|
|
set(next);
|
|
persist(next);
|
|
},
|
|
setProfile: (profile) => {
|
|
set({ profile, tenantId: profile.tenantId });
|
|
usePermissionStore.getState().setProfile(profile.roles, profile.permissions);
|
|
const next = { ...get(), profile };
|
|
persist(next);
|
|
},
|
|
setTenantId: (tenantId) => {
|
|
set({ tenantId });
|
|
const next = { ...get(), tenantId };
|
|
persist(next);
|
|
},
|
|
clearAuth: () => {
|
|
set({
|
|
accessToken: undefined,
|
|
refreshToken: undefined,
|
|
tokenType: undefined,
|
|
expiresInSeconds: undefined,
|
|
profile: undefined
|
|
});
|
|
usePermissionStore.getState().setProfile([], []);
|
|
if (typeof window !== "undefined") localStorage.removeItem(STORAGE_KEY);
|
|
},
|
|
hydrate: () => {
|
|
if (typeof window === "undefined") return;
|
|
const raw = localStorage.getItem(STORAGE_KEY);
|
|
if (!raw) return;
|
|
try {
|
|
const parsed = JSON.parse(raw) as AuthState;
|
|
if (parsed) set(parsed);
|
|
usePermissionStore.getState().setProfile(parsed?.profile?.roles ?? [], parsed?.profile?.permissions ?? []);
|
|
} catch {
|
|
localStorage.removeItem(STORAGE_KEY);
|
|
}
|
|
}
|
|
}));
|
|
|
|
function persist(state: AuthState) {
|
|
if (typeof window === "undefined") return;
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
|
|
}
|