Support authenticated Hugging Face model and component downloads

This commit is contained in:
Mikei386
2026-09-29 11:47:50 +02:00
parent dad67acad8
commit 7f38286f72
13 changed files with 151 additions and 21 deletions
+8
View File
@@ -11,5 +11,13 @@ async function accessPage(){
document.querySelector('#token-generate').onclick=()=>{document.querySelector('#new-token').value=accessToken();document.querySelector('#access-message').textContent='Neuen Token vor dem Speichern kopieren.'};
document.querySelector('#token-show').onclick=()=>{const input=document.querySelector('#new-token');input.type=input.type==='password'?'text':'password';document.querySelector('#token-show').textContent=input.type==='password'?'Token anzeigen':'Token verbergen';};
document.querySelector('#token-copy').onclick=async()=>{try{const token=document.querySelector('#new-token').value;if(!token)throw Error();await navigator.clipboard.writeText(token);document.querySelector('#access-message').textContent='Token kopiert. Bitte sicher speichern.';}catch{document.querySelector('#access-message').textContent='Kopieren nicht möglich. Bitte einen eigenen Token aus dem Passwortmanager verwenden.'}};
const hub=document.createElement('section');hub.className='card';hub.innerHTML=`<h2>Hugging Face · Modelldownloads</h2><p id="hf-status" role="status">Zugang wird geprüft …</p><p>Für private oder freigabepflichtige Modelle: <a class="link" href="https://huggingface.co/settings/tokens" target="_blank" rel="noopener noreferrer">Hugging-Face-Token erstellen ↗</a> mit Leserechten für das gewünschte Repository. Die Freigabe beantragst du auf dessen Modellkarte mit demselben Konto.</p><form id="hf-form"><label>Hugging-Face-Token<input id="hf-token" type="password" autocomplete="off" spellcheck="false" required maxlength="255" placeholder="hf_…"></label><button>Token speichern / ersetzen</button><button id="hf-remove" type="button" class="secondary">Gespeicherten Token entfernen</button></form><p class="note">Separater Zugang für Hugging Face, nicht der Deck-API-Token. Speicherung auf Athena in einer Datei mit Zugriff nur für den Dienstbenutzer (0600), unverschlüsselt. Der gespeicherte Wert wird nie an den Browser zurückgegeben. Bereits laufende Downloads können nach Entfernen weiterlaufen.</p>`;
document.querySelector('#access-page').insertBefore(hub,document.querySelector('#access-message'));
const hfStatus=hub.querySelector('#hf-status');
const describe=s=>s.configured?'Token gespeichert. Ob die Modellfreigabe und Leserechte passen, prüft Hugging Face beim Download.':'Kein Hugging-Face-Token gespeichert. Öffentliche Downloads bleiben möglich.';
try{const r=await fetch('/api/v1/huggingface');if(!r.ok)throw Error();hfStatus.textContent=describe(await r.json());}catch{hfStatus.textContent='Hugging-Face-Zugangsstatus nicht erreichbar.';}
async function saveHub(token){hub.querySelectorAll('button').forEach(b=>b.disabled=true);try{const r=await fetch('/api/v1/huggingface',{method:'POST',headers:{'Content-Type':'application/json','X-Athena-Deck':'1'},body:JSON.stringify({token})}),s=await r.json();if(!r.ok)throw Error(s.error||'Speichern fehlgeschlagen.');hfStatus.textContent=describe(s);}catch(e){hfStatus.textContent=e.message;}finally{hub.querySelector('#hf-token').value='';hub.querySelectorAll('button').forEach(b=>b.disabled=false);}}
hub.querySelector('#hf-form').onsubmit=e=>{e.preventDefault();saveHub(hub.querySelector('#hf-token').value.trim());};
hub.querySelector('#hf-remove').onclick=()=>saveHub(null);
document.querySelector('#logout').onclick=async()=>{const r=await fetch('/api/v1/logout',{method:'POST',headers:{'X-Athena-Deck':'1'}});if(r.ok||r.status===401)location.reload();else document.querySelector('#access-message').textContent='Abmelden fehlgeschlagen. Bitte erneut versuchen.'};
}