ZI Admin — One-Time Key Console health: …

UI ကို HTTPS ထဲထည့်ရင် HTTP API ကို Browser က ပိတ်နိုင်တယ် – ဒီဖိုင်ကို HTTP ပေါ်ကနေဖွင့်ပါ။

Create One-Time Key

Validate Key

result will appear here…
api: apiInput.value.trim(), secret: secretInput.value })); connMsg.textContent = 'Saved.'; setTimeout(()=>connMsg.textContent='', 1500); } async function ping() { const base = apiInput.value.trim().replace(/\/+$/,''); if(!base){ return setHealth('bad','no api'); } try{ const r = await fetch(base + '/healthz', {method:'GET', mode:'cors'}); if(!r.ok){ setHealth('bad', 'http '+r.status); return; } const j = await r.json().catch(()=>({})); setHealth('ok','ok'); return j; }catch(e){ setHealth('bad','offline'); } } function setHealth(state, text){ healthBadge.textContent = text || state; if(state==='ok'){ healthBadge.classList.remove('bad'); healthBadge.classList.add('ok'); } else { healthBadge.classList.remove('ok'); healthBadge.classList.add('bad'); } } async function connect(){ saveLocal(); connMsg.textContent = 'Connecting...'; await ping(); connMsg.textContent = 'Done.'; } async function createKey(){ const base = apiInput.value.trim().replace(/\/+$/,''); const secret = secretInput.value; const path = $('#createPath').value; if(!base || !secret){ return note('keyMsg','API URL / Secret လိုအပ်သည်', true); } try{ const r = await fetch(base + path, { method:'POST', mode:'cors', headers:{'X-Admin-Secret': secret} }); const j = await r.json(); if(!r.ok || !j.ok){ throw new Error(j.error || ('HTTP '+r.status)); } $('#genKey').value = j.key || ''; note('keyMsg','Key generated ✔', false); $('#curlWrap').style.display='none'; }catch(e){ note('keyMsg','Create failed: '+e.message, true); } } function makeCurl(){ const base = apiInput.value.trim().replace(/\/+$/,''); const key = $('#genKey').value.trim(); if(!base || !key){ return; } const cmd = `curl -X POST ${base}/api/validate -H 'Content-Type: application/json' -d '{"key":"${key}"}'`; $('#curlText').textContent = cmd; $('#curlWrap').style.display = 'block'; } async function validate(){ const base = apiInput.value.trim().replace(/\/+$/,''); const path = $('#validatePath').value; const key = $('#valKey').value.trim(); if(!base || !key){ return note('valMsg','API URL / Key လိုအပ်သည်', true); } try{ const r = await fetch(base + path, { method:'POST', mode:'cors', headers:{'Content-Type':'application/json'}, body: JSON.stringify({key}) }); const j = await r.json(); if(!r.ok || !j.ok){ throw new Error(j.error || ('HTTP '+r.status)); } note('valMsg','✓ valid (one-time consumed)', false); }catch(e){ note('valMsg','✗ '+e.message, true); } } function note(id, text, isErr){ const el = $('#'+id); el.textContent = text; el.style.color = isErr ? 'var(--bad)' : 'var(--ok)'; clearTimeout(el._t); el._t = setTimeout(()=>{ el.textContent=''; }, 3000); } async function copyKey(){ const v = $('#genKey').value.trim(); if(!v) return; try{ await navigator.clipboard.writeText(v); note('keyMsg','Copied.', false); }catch(_){ note('keyMsg','Copy failed.', true); } } // Bind $('#btnSave').onclick = saveLocal; $('#btnHealth').onclick = ping; $('#btnConnect').onclick = connect; $('#btnCreate').onclick = createKey; $('#btnCopy').onclick = copyKey; $('#btnMakeCurl').onclick = makeCurl; $('#btnValidate').onclick = validate; // First health check (if URL saved) if(apiInput.value) ping();