Add email field to users, login accepts email or username

This commit is contained in:
2026-04-13 13:55:26 +00:00
parent 845d6e4fbe
commit 00e76e412d
3 changed files with 27 additions and 12 deletions
+10 -5
View File
@@ -74,16 +74,20 @@ tr:hover td{background:var(--surface2)}
<h3>Create User</h3>
<div class="form-row">
<div class="field"><label>Username</label><input id="nu-user" placeholder="username"></div>
<div class="field"><label>Password</label><input type="password" id="nu-pass"></div>
<div class="field"><label>Email</label><input type="email" id="nu-email" placeholder="user@example.com"></div>
</div>
<div class="form-row">
<div class="field"><label>Password</label><input type="password" id="nu-pass"></div>
<div class="field"><label>Display Name</label><input id="nu-name" placeholder="Full Name"></div>
</div>
<div class="form-row">
<div class="field"><label>Role</label><select id="nu-role"><option value="user">User</option><option value="admin">Admin</option></select></div>
<div class="field"></div>
</div>
<button class="btn btn-primary" onclick="createUser()">Create</button>
<span class="msg" id="nu-msg"></span>
</div>
<table id="users-table"><thead><tr><th>Username</th><th>Display Name</th><th>Role</th><th>Agents</th><th>Actions</th></tr></thead><tbody></tbody></table>
<table id="users-table"><thead><tr><th>Username</th><th>Email</th><th>Display Name</th><th>Role</th><th>Agents</th><th>Actions</th></tr></thead><tbody></tbody></table>
</div>
<!-- Catalog -->
@@ -154,16 +158,17 @@ async function loadUsers(){
const res=await fetch(API+'/api/admin/users');if(res.status===403||res.status===401){location.href='/';return}
const users=await res.json();
document.querySelector('#users-table tbody').innerHTML=users.map(u=>`<tr>
<td>${u.username}</td><td>${u.display_name}</td><td><span class="badge ${u.role}">${u.role}</span></td>
<td>${u.username}</td><td style="font-size:.8rem">${u.email||'<span style="color:var(--yellow)">none</span>'}</td><td>${u.display_name}</td><td><span class="badge ${u.role}">${u.role}</span></td>
<td>${u.instance_count}</td>
<td><div class="action-btns"><button class="btn btn-danger btn-sm" onclick="deleteUser(${u.id},'${u.username}')">Delete</button></div></td>
</tr>`).join('');
}
async function createUser(){
const res=await fetch(API+'/api/admin/users',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({
username:document.getElementById('nu-user').value,password:document.getElementById('nu-pass').value,
username:document.getElementById('nu-user').value,email:document.getElementById('nu-email').value,
password:document.getElementById('nu-pass').value,
display_name:document.getElementById('nu-name').value,role:document.getElementById('nu-role').value})});
if(res.ok){showMsg('nu-msg','Created',true);loadUsers();document.getElementById('nu-user').value='';document.getElementById('nu-pass').value='';document.getElementById('nu-name').value=''}
if(res.ok){showMsg('nu-msg','Created',true);loadUsers();['nu-user','nu-email','nu-pass','nu-name'].forEach(id=>document.getElementById(id).value='')}
else{const e=await res.json();showMsg('nu-msg',e.detail||'Error',false)}
}
async function deleteUser(id,name){if(!confirm('Delete user '+name+'?'))return;await fetch(API+'/api/admin/users/'+id,{method:'DELETE'});loadUsers()}