/* Settings form stays mounted while status polling updates only status elements. */ let networkBusy=false, networkState=null; async function networkRequest(action,body={}){ const response=await fetch('/api/v1/network'+(action?'/'+action:''),{method:action?'POST':'GET',headers:action?{'Content-Type':'application/json','X-Athena-Deck':'1'}:{},body:action?JSON.stringify(body):undefined,signal:AbortSignal.timeout(40000)}); const value=await response.json();if(response.status===401){location.reload();throw Error('Bitte erneut anmelden.')}if(!response.ok)throw Error(value.error||'Netzwerkaktion fehlgeschlagen.');return value; } async function networkAction(action,body={}){ if(networkBusy)return;networkBusy=true;networkButtons(); const output=document.querySelector('#network-message');output.textContent='Wird ausgeführt …'; try{await networkRequest(action,body);output.textContent=action==='import'?'Konfiguration geprüft und geschützt auf Athena gespeichert.':action==='install'?'Installation läuft. Der Status aktualisiert sich automatisch.':'Einstellung übernommen.';} catch(e){output.textContent=e.message;} finally{networkBusy=false;await networkPage();} } function networkButtons(){ if(!networkState)return; const s=networkState; document.querySelectorAll('#network-page button').forEach(b=>b.disabled=networkBusy||s.state==='installing'); const set=(id,disabled)=>{const b=document.getElementById(id);if(b)b.disabled=b.disabled||disabled;}; set('network-install',s.installed||s.install_supported===false); set('network-import',!s.installed||s.enabled||s.mode!=='lan'||!!s.pending); set('network-connect',!s.configured||s.enabled); set('network-disconnect',!s.enabled); set('network-delete',!s.configured||s.enabled||s.mode!=='lan'||!!s.pending); set('network-apply',!s.installed||!!s.pending); const needed=s.pending?.target==='lan'?'lan':'tunnel'; set('network-confirm',!s.pending||s.ingress!==needed); set('network-cancel',!s.pending); } async function networkPage(){ const view=document.querySelector('#view'); if(!document.querySelector('#network-page')){ view.innerHTML=`
EINSTELLUNGEN / NETZWERK

Dein Weg zu Athena.

Ein eigener WireGuard-Zugang für Athena Deck und seine internen API-Endpunkte.

WireGuard-Modul

Wird geprüft …

Auf Athena einrichten

Installiert WireGuard und Deck in einem eigenen Container. Der vorhandene Gateway bleibt unverändert. Die erste Einrichtung startet im LAN-Modus auf Port 8110.

Vor der Installation kopieren und sicher speichern. Dieser Token ist vom lokalen Mac-Zugang getrennt.

Benötigt den vorhandenen SSH-Zugang und Docker auf Athena. LAN-Zugriff verwendet HTTP; für vertrauliche Eingaben WireGuard oder SSH-Tunnel verwenden.

Zugriff auf Deck und API

Der lokale Mac-Zugang per SSH bleibt als Verwaltungskanal erhalten. Produktionsendpunkte werden nicht umgestellt. Im Modus „Nur Tunnel“ gibt es bei Tunnelausfall keinen LAN-Fallback.

`; document.querySelector('#network-install').onclick=()=>{const input=document.querySelector('#network-password'),password=input.value,token=document.querySelector('#network-api-token'),api_token=token.value;input.value='';token.value='';networkAction('install',{password,api_token});}; document.querySelector('#network-generate-token').onclick=()=>{document.querySelector('#network-api-token').value=accessToken();}; document.querySelector('#network-show-token').onclick=()=>{const input=document.querySelector('#network-api-token');input.type=input.type==='password'?'text':'password';document.querySelector('#network-show-token').textContent=input.type==='password'?'API-Token anzeigen':'API-Token verbergen';}; document.querySelector('#network-copy-token').onclick=async()=>{try{const token=document.querySelector('#network-api-token').value;if(!token)throw Error();await navigator.clipboard.writeText(token);document.querySelector('#network-message').textContent='API-Token kopiert. Bitte sicher speichern.';}catch{document.querySelector('#network-message').textContent='Kopieren nicht möglich. Bitte eigenen Token verwenden.'}}; document.querySelector('#network-import').onclick=async()=>{const input=document.querySelector('#network-file'),file=input.files[0];if(!file){document.querySelector('#network-message').textContent='Bitte zuerst eine .conf-Datei auswählen.';return}if(file.size>16384){document.querySelector('#network-message').textContent='Die Datei darf höchstens 16 KiB groß sein.';return}const config=await file.text();input.value='';await networkAction('import',{config});}; for(const action of ['connect','disconnect','delete','cancel'])document.querySelector('#network-'+action).onclick=()=>networkAction(action); document.querySelector('#network-apply').onclick=()=>networkAction('mode',{mode:document.querySelector('#network-mode').value}); document.querySelector('#network-confirm').onclick=()=>networkAction('confirm',{trial_id:networkState?.pending?.id}); } try{ const s=await networkRequest('');if(!document.querySelector('#network-page'))return;networkState=s; const labels={'disabled-module':'Nicht angebunden',unavailable:'Nicht bereit',installing:'Installation läuft',disabled:'Deaktiviert',connecting:'Warte auf Handshake',connected:'Verbunden'}; document.querySelector('#network-state').textContent=labels[s.state]||'Nicht verfügbar'; const details=document.querySelector('#network-details');details.replaceChildren(); for(const [label,value] of [['Konfiguration',s.configured?'Gespeichert':'Keine'],['Letzter Handshake',s.latest_handshake?new Date(s.latest_handshake*1000).toLocaleString('de-DE'):'Noch keiner'],['Dieser Zugang',s.ingress==='management'?'Mac / SSH-Verwaltung':s.ingress==='tunnel'?'WireGuard-Tunnel':'LAN']]){const d=document.createElement('div'),small=document.createElement('small'),strong=document.createElement('strong');small.textContent=label;strong.textContent=value;d.append(small,strong);details.append(d);} for(const [label,url] of [['LAN',s.lan_url],['Tunnel',s.tunnel_url]])if(url){const d=document.createElement('div'),a=document.createElement('a');a.href=url+'/#network';a.textContent=label+': '+url;a.target='_blank';a.rel='noopener';d.append(a);details.append(d);} document.querySelector('#network-setup').hidden=!!s.installed; document.querySelector('#network-config').hidden=false; document.querySelector('#network-file').disabled=!s.installed||s.enabled||networkBusy; document.querySelector('#network-access').hidden=false; document.querySelector('#network-mode').disabled=!s.installed||!!s.pending||networkBusy; document.querySelector('#network-notice').textContent=[s.error,s.job?.message,...(s.warnings||[])].filter(Boolean).join(' '); document.querySelector('#network-current').textContent='Aktuell: '+({lan:'Nur lokales Netzwerk',tunnel:'Nur WireGuard-Tunnel',both:'Tunnel und LAN'}[s.mode]||'Noch nicht eingerichtet'); document.querySelector('#network-trial').hidden=!s.pending; if(s.pending)document.querySelector('#network-countdown').textContent=`Test aktiv · ${s.pending.seconds_remaining} Sekunden bis zur automatischen Rücknahme. Bestätigung nötig über ${s.pending.target==='lan'?'LAN':'WireGuard'}.`; networkButtons(); }catch(e){if(document.querySelector('#network-message'))document.querySelector('#network-message').textContent=e.message;} }