import { currentUser } from "@workspace/ui/services/admin/user"; import { isBrowser } from "@workspace/ui/utils/index"; import { create } from "zustand"; export interface GlobalStore { common: API.GetGlobalConfigResponse; user?: API.User; setCommon: (common: Partial) => void; setUser: (user?: API.User) => void; getUserInfo: () => Promise; getUserSubscribe: (short: string, token: string, type?: string) => string[]; getAppSubLink: (url: string, schema?: string) => string; } /** * Extracts the full domain or root domain from a URL. * * @param url - The URL to extract the domain from. * @param extractRoot - If true, extracts the root domain (e.g., example.com). If false, extracts the full domain (e.g., sub.example.com). * @returns The extracted domain or root domain, or null if the URL is invalid. */ export function extractDomain(url: string, extractRoot = true): string | null { try { const { hostname } = new URL(url); if (/^\d{1,3}(\.\d{1,3}){3}$/.test(hostname)) { return hostname; } const domainParts = hostname.split(".").filter(Boolean); if (extractRoot && domainParts.length > 2) { return domainParts.slice(-2).join("."); } return hostname; } catch (error) { console.error("Invalid URL:", error); return null; } } export const useGlobalStore = create((set, get) => ({ common: { site: { host: "", site_name: "", site_desc: "", site_logo: "", keywords: "", custom_html: "", custom_data: "", }, verify: { turnstile_site_key: "", captcha_type: "turnstile", enable_login_verify: false, enable_register_verify: false, enable_reset_password_verify: false, enable_user_login_captcha: false, enable_user_register_captcha: false, enable_user_reset_password_captcha: false, enable_admin_login_captcha: false, }, auth: { mobile: { enable: false, enable_whitelist: false, whitelist: [], }, email: { enable: false, enable_verify: false, enable_domain_suffix: false, domain_suffix_list: "", }, register: { stop_register: false, enable_ip_register_limit: false, ip_register_limit: 0, ip_register_limit_duration: 0, }, device: { enable: false, show_ads: false, enable_security: false, only_real_device: false, }, }, invite: { forced_invite: false, referral_percentage: 0, only_first_purchase: false, }, currency: { currency_unit: "USD", currency_symbol: "$", }, subscribe: { single_model: false, subscribe_path: "", subscribe_domain: "", pan_domain: false, user_agent_limit: false, user_agent_list: "", }, verify_code: { verify_code_expire_time: 5, verify_code_limit: 15, verify_code_interval: 60, }, oauth_methods: [], web_ad: false, }, user: undefined, setCommon: (common) => set((state) => ({ common: { ...state.common, ...common, }, })), setUser: (user) => set({ user }), getUserInfo: async () => { try { const { data } = await currentUser(); set({ user: data.data }); } catch (error) { console.error("Failed to refresh user:", error); } }, getUserSubscribe: (short: string, token: string, type?: string) => { const { pan_domain, subscribe_domain, subscribe_path } = get().common.subscribe || {}; const domains = subscribe_domain ? subscribe_domain.split("\n") : [extractDomain(window.location.origin, pan_domain)]; return domains.map((domain) => { if (pan_domain) { if (type) return `https://${short}.${type}.${domain}${subscribe_path}?token=${token}&type=${type}`; return `https://${short}.${domain}${subscribe_path}?token=${token}`; } if (type) return `https://${domain}${subscribe_path}?token=${token}&type=${type}`; return `https://${domain}${subscribe_path}?token=${token}`; }); }, getAppSubLink: (url: string, schema?: string) => { const name = get().common?.site?.site_name || ""; if (!schema) return "url"; try { let result = schema.replace(/\${url}/g, url).replace(/\${name}/g, name); const maxLoop = 10; let prev: string; let loop = 0; do { prev = result; result = result.replace( /\${encodeURIComponent\(JSON\.stringify\(([^)]+)\)\)}/g, (match, expr) => { try { const processedExpr = expr .replace(/url/g, `"${url}"`) .replace(/name/g, `"${name}"`); if (processedExpr.includes("server_remote")) { const serverRemoteValue = `${url}, tag=${name}`; return encodeURIComponent( JSON.stringify({ server_remote: [serverRemoteValue] }) ); } const obj = eval(`(${processedExpr})`); return encodeURIComponent(JSON.stringify(obj)); } catch { return match; } } ); result = result.replace( /\${encodeURIComponent\(([^)]+)\)}/g, (match, expr) => { if (expr === "url") return encodeURIComponent(url); if (expr === "name") return encodeURIComponent(name); try { return encodeURIComponent(expr); } catch { return match; } } ); result = result.replace( /\${window\.btoa\(([^)]+)\)}/g, (match, expr) => { const btoa = isBrowser() ? window.btoa : (str: string) => str; if (expr === "url") return btoa(url); if (expr === "name") return btoa(name); try { return btoa(expr); } catch { return match; } } ); result = result.replace( /\${JSON\.stringify\(([^}]+)\)}/g, (match, expr) => { try { const processedExpr = expr .replace(/url/g, `"${url}"`) .replace(/name/g, `"${name}"`); if (processedExpr.includes("server_remote")) { const serverRemoteValue = `${url}, tag=${name}`; return JSON.stringify({ server_remote: [serverRemoteValue] }); } const result = eval(`(${processedExpr})`); return JSON.stringify(result); } catch { return match; } } ); loop++; } while (result !== prev && loop < maxLoop); return result; } catch (_error) { return ""; } }, }));