"use client"; import { useEffect, useState, useRef } from "react"; import { useRouter } from "next/navigation"; import { motion, AnimatePresence } from "framer-motion"; import { Shield, ShieldAlert, ShieldCheck, Loader2, Terminal, } from "lucide-react"; import { CyberButton } from "@/components/ui/cyber-button"; import { Dictionary } from "@/lib/IDict"; declare global { interface Window { onTelegramAuth: (user: any) => void; } } interface AuthClientProps { dict: Dictionary["auth"]; lang: string; } export function AuthClient({ dict, lang }: AuthClientProps) { const router = useRouter(); const [status, setStatus] = useState< "processing" | "granted" | "denied" | "awaiting" >("processing"); const [logs, setLogs] = useState([]); const tgContainerRef = useRef(null); const initialized = useRef(false); const widgetInjected = useRef(false); useEffect(() => { if (initialized.current) return; initialized.current = true; const authenticate = async () => { setLogs((prev) => [...prev, `> ${dict.processing}`]); await new Promise((resolve) => setTimeout(resolve, 800)); const hash = window.location.hash; let token = localStorage.getItem("nrxp_token"); const searchParams = new URLSearchParams(window.location.search); const queryToken = searchParams.get("token"); if (queryToken) { token = queryToken; searchParams.delete("token"); const newSearch = searchParams.toString(); const newUrl = window.location.pathname + (newSearch ? `?${newSearch}` : "") + window.location.hash; window.history.replaceState(null, "", newUrl); } else if (hash.includes("token=")) { const params = new URLSearchParams(hash.replace("#", "?")); const urlToken = params.get("token"); if (urlToken) { token = urlToken; window.history.replaceState( null, "", window.location.pathname + window.location.search, ); } } if (!token) { setLogs((prev) => [...prev, dict.logs.waitInit]); setStatus("awaiting"); return; } if (status !== "processing") setStatus("processing"); setLogs((prev) => [...prev, `> ${dict.verifying}`]); try { const API_BASE = process.env.NEXT_PUBLIC_API_URL || "/api"; const res = await fetch(`${API_BASE}/me`, { headers: { Authorization: `Bearer ${token}` }, }); if (res.ok) { localStorage.setItem("nrxp_token", token); setLogs((prev) => [...prev, dict.logs.sigValid]); setStatus("granted"); setLogs((prev) => [...prev, `> ${dict.redirecting}`]); setTimeout(() => router.push(`/${lang}/profile`), 1500); } else { localStorage.removeItem("nrxp_token"); setLogs((prev) => [...prev, dict.logs.apiRejected]); setStatus("awaiting"); } } catch (err) { setLogs((prev) => [...prev, dict.logs.coreOffline]); setStatus("denied"); } }; authenticate(); }, [dict, lang, router]); useEffect(() => { window.onTelegramAuth = async (user: any) => { setStatus("processing"); setLogs((prev) => [...prev, dict.logs.authPayload, dict.logs.verifyHmac]); try { const API_BASE = process.env.NEXT_PUBLIC_API_URL || "/api"; const res = await fetch(`${API_BASE}/auth/telegram`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(user), }); if (res.ok) { const data = await res.json(); localStorage.setItem("nrxp_token", data.token); setLogs((prev) => [ ...prev, dict.logs.sigValid, `> ${dict.redirecting}`, ]); setStatus("granted"); setTimeout(() => router.push(`/${lang}/profile`), 1500); } else { setLogs((prev) => [...prev, dict.logs.invalidSig]); setStatus("denied"); } } catch (e) { setLogs((prev) => [...prev, dict.logs.networkError]); setStatus("denied"); } }; }, [dict, lang, router]); useEffect(() => { if ( status === "awaiting" && tgContainerRef.current && !widgetInjected.current ) { widgetInjected.current = true; const script = document.createElement("script"); script.src = "https://telegram.org/js/telegram-widget.js?22"; script.async = true; script.setAttribute( "data-telegram-login", process.env.NEXT_PUBLIC_BOT_USERNAME || "ntrnr_vpn_bot", ); script.setAttribute("data-size", "large"); script.setAttribute("data-onauth", "onTelegramAuth(user)"); script.setAttribute("data-request-access", "write"); tgContainerRef.current.appendChild(script); } }, [status]); return (
{status === "processing" && (
)} {status === "granted" && (
)} {status === "denied" && (
)} {status === "awaiting" && (
)}

{status === "processing" ? dict.title : status === "granted" ? dict.granted : status === "awaiting" ? dict.awaiting : dict.denied}

{logs.map((log, i) => ( {log} ))} {status === "processing" && (
_
)}
{status === "denied" && (

{dict.noToken}

{dict.toBot}
)} {status === "awaiting" && (

{dict.authPrompt}

)}
); }