diff --git a/server/templates/index.html b/server/templates/index.html index c5c6ee7..9ea7ddd 100644 --- a/server/templates/index.html +++ b/server/templates/index.html @@ -350,17 +350,35 @@ async function importAndPush(){ await importFiles(); setTimeout(pushAll,300); } async function loadExport(){ document.getElementById('dc-export').value=await(await fetch('/hydra/domain.conf')).text(); document.getElementById('il-export').value=await(await fetch('/hydra/ip.list')).text(); } // ── ROUTERS ─────────────────────────────────────────────────────────────── +function _escHtml(s){ return String(s==null?'':s).replace(/&/g,'&').replace(//g,'>'); } +(function _bindRouterList(){ + const box=document.getElementById('routers-list'); + if(!box||box.dataset.actBind==='1') return; + box.dataset.actBind='1'; + box.addEventListener('click',async (e)=>{ + const b=e.target.closest('button[data-r-act]'); + if(!b) return; + const n=decodeURIComponent(b.getAttribute('data-router')||''); + const act=b.getAttribute('data-r-act'); + if(act==='test') await testRouter(n); + else if(act==='pull') await pullRouter(n); + else if(act==='del') await delRouter(n); + }); +})(); async function loadRouters(){ const R=await(await fetch('/api/routers')).json(); const el=document.getElementById('routers-list'); if(!Object.keys(R).length){ el.innerHTML='Роутеры не добавлены'; return; } - el.innerHTML=Object.entries(R).map(([n,c])=>`
-
${n} — ${c.ip||'—'}
+ el.innerHTML=Object.entries(R).map(([n,c])=>{ + const enc=encodeURIComponent(n); + return `
+
${_escHtml(n)} — ${_escHtml(c.ip||'—')}
- - - -
`).join(''); + + + +
`; + }).join(''); } async function addRouter(){ const n=document.getElementById('r-name').value.trim(); if(!n)return; const b={ip:document.getElementById('r-ip').value.trim(),user:document.getElementById('r-user').value||'root',password:document.getElementById('r-pass').value}; try{ await fetch('/api/routers/'+encodeURIComponent(n),{method:'POST',headers:authHdr(),body:JSON.stringify(b)}); sm('rm','ok','✅ '+n); loadRouters(); }catch(e){sm('rm','err','❌ '+e)} } async function delRouter(n){ if(!confirm('Удалить '+n+'?'))return; await fetch('/api/routers/'+encodeURIComponent(n),{method:'DELETE',headers:{'X-Admin-Password':getPass()}}); loadRouters(); }