100 lines
3.3 KiB
JavaScript
100 lines
3.3 KiB
JavaScript
import { apiDelete, apiGet, apiPost, apiPut, isAuthRedirectError } from '../api.js';
|
|
import { guard } from '../core/auth-guard.js';
|
|
import { esc } from '../core/utils.js';
|
|
|
|
const loadingEl = document.getElementById('page-loading');
|
|
const mainEl = document.getElementById('page-main');
|
|
const errEl = document.getElementById('page-error');
|
|
|
|
function showError(msg) {
|
|
loadingEl.hidden = true;
|
|
mainEl.hidden = true;
|
|
errEl.hidden = false;
|
|
errEl.textContent = msg;
|
|
}
|
|
|
|
function formatName(u) {
|
|
const a = [u.firstName, u.lastName].filter(Boolean);
|
|
return a.length ? a.map((x) => esc(String(x))).join(' ') : '—';
|
|
}
|
|
|
|
function renderRows(users) {
|
|
const tbody = document.getElementById('users-table-body');
|
|
tbody.innerHTML = users
|
|
.map(
|
|
(u) => `
|
|
<tr data-id="${esc(u.id)}">
|
|
<td>${esc(u.username)}</td>
|
|
<td class="muted">${formatName(u)}</td>
|
|
<td><span class="badge">${u.role === 'admin' ? 'Admin' : 'Benutzer'}</span></td>
|
|
<td class="muted">${u.source === 'ldap' ? 'LDAP' : 'Lokal'}</td>
|
|
<td>${u.active ? 'Ja' : 'Nein'}</td>
|
|
<td class="users-actions">
|
|
${u.source === 'local' ? `<button type="button" class="secondary btn-pw" data-id="${esc(u.id)}">Passwort</button>` : ''}
|
|
<button type="button" class="secondary btn-toggle" data-id="${esc(u.id)}" data-active="${u.active ? '1' : '0'}">${u.active ? 'Deaktivieren' : 'Aktivieren'}</button>
|
|
<button type="button" class="danger btn-del-user" data-id="${esc(u.id)}">Löschen</button>
|
|
</td>
|
|
</tr>`,
|
|
)
|
|
.join('');
|
|
}
|
|
|
|
async function run() {
|
|
const users = await apiGet('/users');
|
|
renderRows(users);
|
|
|
|
document.getElementById('form-new-user').onsubmit = async (e) => {
|
|
e.preventDefault();
|
|
const fd = new FormData(e.target);
|
|
await apiPost('/users', {
|
|
username: fd.get('username'),
|
|
password: fd.get('password'),
|
|
role: fd.get('role'),
|
|
});
|
|
e.target.reset();
|
|
location.reload();
|
|
};
|
|
|
|
const root = document.getElementById('page-main');
|
|
root.querySelectorAll('.btn-pw').forEach((btn) => {
|
|
btn.onclick = async () => {
|
|
const uid = btn.getAttribute('data-id');
|
|
const pw = window.prompt('Neues Passwort (min. 8 Zeichen):');
|
|
if (!pw || pw.length < 8) return;
|
|
await apiPut(`/users/${uid}`, { password: pw });
|
|
location.reload();
|
|
};
|
|
});
|
|
root.querySelectorAll('.btn-toggle').forEach((btn) => {
|
|
btn.onclick = async () => {
|
|
const uid = btn.getAttribute('data-id');
|
|
const active = btn.getAttribute('data-active') === '1';
|
|
await apiPut(`/users/${uid}`, { active: !active });
|
|
location.reload();
|
|
};
|
|
});
|
|
root.querySelectorAll('.btn-del-user').forEach((btn) => {
|
|
btn.onclick = async () => {
|
|
if (!window.confirm('Benutzer wirklich löschen?')) return;
|
|
const uid = btn.getAttribute('data-id');
|
|
await apiDelete(`/users/${uid}`);
|
|
location.reload();
|
|
};
|
|
});
|
|
}
|
|
|
|
async function init() {
|
|
const st = await guard({ needsAdmin: true, activeNav: 'users' });
|
|
if (!st) return;
|
|
loadingEl.hidden = true;
|
|
mainEl.hidden = false;
|
|
try {
|
|
await run();
|
|
} catch (e) {
|
|
if (isAuthRedirectError(e)) return;
|
|
showError(e.message || 'Fehler');
|
|
}
|
|
}
|
|
|
|
init();
|