61 lines
2.9 KiB
JavaScript
61 lines
2.9 KiB
JavaScript
/* Identity editing: admin-protected API, optimistic revision checks, no HTML injection. */
|
|
(() => {
|
|
'use strict';
|
|
const $=id=>document.getElementById(id);
|
|
let csrf='',revision='',dirty=false,busy=false;
|
|
const msg=(s,error=false,id='idMessage')=>{const e=$(id);e.textContent=s;e.classList.toggle('error',error);};
|
|
const setName=name=>{
|
|
const n=String(name||'Assistant').trim();
|
|
const initial=Array.from(n)[0]?.toLocaleUpperCase('fr-FR')||'A';
|
|
$('idName').textContent=n;$('idInitial').textContent=initial;
|
|
$('idActiveName').textContent=n;$('idAvatar').textContent=initial;
|
|
document.title='Identité · '+n;
|
|
};
|
|
function updateCount(){$('idCount').textContent=$('idText').value.length.toLocaleString('fr-FR')+' caractères';}
|
|
async function jsonFetch(url,options={}){
|
|
const r=await fetch(url,{credentials:'same-origin',cache:'no-store',...options});
|
|
const d=await r.json().catch(()=>({}));
|
|
if(!r.ok)throw Error(d.error||'Erreur HTTP '+r.status);
|
|
return d;
|
|
}
|
|
async function auth(){
|
|
const a=await jsonFetch('/api/control/auth');
|
|
csrf=a.csrf||'';
|
|
$('idLoginPanel').hidden=!!a.authenticated;
|
|
$('idEditor').hidden=!a.authenticated;
|
|
$('idBadge').textContent=a.authenticated?'Administrateur connecté':'Connexion requise';
|
|
$('idBadge').classList.toggle('ok',!!a.authenticated);
|
|
if(a.authenticated)await load();
|
|
}
|
|
async function load(){
|
|
try{
|
|
const d=await jsonFetch('/api/control/identity');
|
|
$('idText').value=d.text;revision=d.revision;dirty=false;
|
|
setName(d.name);updateCount();msg('Document chargé.');
|
|
}catch(e){msg(e.message,true);}
|
|
}
|
|
$('idLoginForm').addEventListener('submit',async e=>{
|
|
e.preventDefault();
|
|
try{
|
|
await jsonFetch('/api/control/login',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({password:$('idPassword').value})});
|
|
$('idPassword').value='';await auth();
|
|
}catch(err){msg(err.message,true,'idLoginMessage');}
|
|
});
|
|
$('idText').addEventListener('input',()=>{dirty=true;updateCount();msg('Modifications non enregistrées.');});
|
|
$('idSave').addEventListener('click',async()=>{
|
|
if(busy||!revision)return;
|
|
busy=true;$('idSave').disabled=true;
|
|
try{
|
|
const d=await jsonFetch('/api/control/identity',{
|
|
method:'POST',headers:{'Content-Type':'application/json','X-Alfred-CSRF':csrf},
|
|
body:JSON.stringify({text:$('idText').value,revision})
|
|
});
|
|
revision=d.revision;dirty=false;msg(d.updated?'Identité enregistrée. Nouvelle version sauvegardée.':'Aucun changement à enregistrer.');
|
|
}catch(e){msg(e.message,true);}
|
|
finally{busy=false;$('idSave').disabled=false;}
|
|
});
|
|
$('idReload').addEventListener('click',()=>{if(dirty&&!confirm('Abandonner les modifications non enregistrées ?'))return;load();});
|
|
window.addEventListener('beforeunload',event=>{if(dirty){event.preventDefault();event.returnValue='';}});
|
|
auth().catch(e=>{msg(e.message,true,'idLoginMessage');$('idLoginPanel').hidden=false;});
|
|
})();
|