Fix leere Nutzertabelle: Fehler-Handler + DB-Fallback fuer loadUsers
- admin.js: .fail() Handler zeigt Fehlermeldung in der Tabelle statt stille Leere - server.js: Fallback-Query (SELECT *) wenn role/created_at Spalten fehlen - Server loggt DB-Fehler statt sie zu verschlucken Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -26,12 +26,18 @@ $(document).ready(function() {
|
|||||||
$('#users-tbody').empty();
|
$('#users-tbody').empty();
|
||||||
$('#user-select').html('<option value="">Nutzer waehlen...</option>');
|
$('#user-select').html('<option value="">Nutzer waehlen...</option>');
|
||||||
|
|
||||||
|
if (!users || users.length === 0) {
|
||||||
|
$('#users-tbody').html('<tr><td colspan="5" style="text-align:center;">Keine Nutzer gefunden</td></tr>');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
users.forEach(function(u) {
|
users.forEach(function(u) {
|
||||||
var badge = '<span class="badge badge-' + u.role + '">' + u.role + '</span>';
|
var role = u.role || 'unbekannt';
|
||||||
|
var badge = '<span class="badge badge-' + role + '">' + role + '</span>';
|
||||||
var created = u.created_at ? new Date(u.created_at).toLocaleDateString('de-DE') : '-';
|
var created = u.created_at ? new Date(u.created_at).toLocaleDateString('de-DE') : '-';
|
||||||
var info = created;
|
var info = created;
|
||||||
|
|
||||||
if (u.role === 'client' && u.expires_at) {
|
if (role === 'client' && u.expires_at) {
|
||||||
var expDate = new Date(u.expires_at).toLocaleDateString('de-DE');
|
var expDate = new Date(u.expires_at).toLocaleDateString('de-DE');
|
||||||
if (u.expired) {
|
if (u.expired) {
|
||||||
badge = '<span class="badge badge-expired">abgelaufen</span>';
|
badge = '<span class="badge badge-expired">abgelaufen</span>';
|
||||||
@@ -46,15 +52,18 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
$('#users-tbody').append(
|
$('#users-tbody').append(
|
||||||
'<tr><td>' + u.id + '</td><td>' + u.username + ' ' + badge +
|
'<tr><td>' + u.id + '</td><td>' + u.username + ' ' + badge +
|
||||||
'</td><td>' + u.role + '</td><td>' + info +
|
'</td><td>' + role + '</td><td>' + info +
|
||||||
'</td><td>' + actions + '</td></tr>'
|
'</td><td>' + actions + '</td></tr>'
|
||||||
);
|
);
|
||||||
|
|
||||||
// Dropdown fuer Ordner-Zuweisung (nur non-admin)
|
// Dropdown fuer Ordner-Zuweisung (nur non-admin)
|
||||||
if (u.role !== 'admin') {
|
if (role !== 'admin') {
|
||||||
$('#user-select').append('<option value="' + u.id + '">' + u.username + ' (' + u.role + ')</option>');
|
$('#user-select').append('<option value="' + u.id + '">' + u.username + ' (' + role + ')</option>');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}).fail(function(xhr) {
|
||||||
|
var msg = 'HTTP ' + xhr.status + ': ' + xhr.statusText;
|
||||||
|
$('#users-tbody').html('<tr><td colspan="5" style="color:#e44d26;">Fehler beim Laden: ' + msg + '</td></tr>');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
assets/js/admin.min.js
vendored
2
assets/js/admin.min.js
vendored
@@ -1 +1 @@
|
|||||||
$(document).ready(function(){function e(){$.get("/api/admin/users").done(function(e){$("#users-tbody").empty(),$("#user-select").html('<option value="">Nutzer waehlen...</option>'),e.forEach(function(e){var n='<span class="badge badge-'+e.role+'">'+e.role+"</span>",a=e.created_at?new Date(e.created_at).toLocaleDateString("de-DE"):"-";if("client"===e.role&&e.expires_at){var t=new Date(e.expires_at).toLocaleDateString("de-DE");e.expired?(n='<span class="badge badge-expired">abgelaufen</span>',a="Abgelaufen: "+t):a="Bis: "+t}var r='<button class="btn-small" onclick="changePassword('+e.id+", '"+e.username.replace(/'/g,"\\'")+"')\">PW</button>";r+='<button class="btn-small" onclick="deleteUser('+e.id+", '"+e.username.replace(/'/g,"\\'")+"')\">X</button>",$("#users-tbody").append("<tr><td>"+e.id+"</td><td>"+e.username+" "+n+"</td><td>"+e.role+"</td><td>"+a+"</td><td>"+r+"</td></tr>"),"admin"!==e.role&&$("#user-select").append('<option value="'+e.id+'">'+e.username+" ("+e.role+")</option>")})})}$.get("/api/auth/me").done(function(n){"admin"!==n.role?(alert("Kein Zugriff!"),window.location.href="/"):(e(),$.get("/api/admin/folders").done(function(e){$("#folder-checkboxes").empty(),0!==e.length?e.forEach(function(e){$("#folder-checkboxes").append('<div class="folder-check"><label><input type="checkbox" value="'+e+'" class="folder-cb"/> <i class="fa fa-folder"></i> '+e+"</label></div>")}):$("#folder-checkboxes").html("<p>Keine Unterordner in Websitebilder gefunden. Erstelle Ordner in Nextcloud.</p>")}),$("body").removeClass("is-preload"))}).fail(function(){window.location.href="/"}),$("#logout-btn").click(function(e){e.preventDefault(),$.post("/api/auth/logout").done(function(){window.location.href="/"})}),$("#create-user-form").submit(function(n){n.preventDefault();var a=$("#new-username").val().trim(),t=$("#new-password").val(),r=$("#new-role").val();a&&t?$.ajax({url:"/api/admin/users",type:"POST",contentType:"application/json",data:JSON.stringify({username:a,password:t,role:r})}).done(function(n){alert('Nutzer "'+a+'" erfolgreich erstellt!'),$("#new-username").val(""),$("#new-password").val(""),e()}).fail(function(e){var n="Unbekannter Fehler";e.responseJSON&&e.responseJSON.error?n=e.responseJSON.error:e.status&&(n="HTTP "+e.status+": "+e.statusText),alert("Fehler beim Erstellen: "+n)}):alert("Bitte Username und Passwort eingeben.")}),window.deleteUser=function(n,a){confirm('Nutzer "'+a+'" wirklich loeschen?')&&$.ajax({url:"/api/admin/users/"+n,type:"DELETE"}).done(e).fail(function(e){alert(e.responseJSON?e.responseJSON.error:"Fehler")})},window.changePassword=function(e,n){var a=prompt('Neues Passwort fuer "'+n+'":');a&&$.ajax({url:"/api/admin/users/"+e+"/password",type:"PUT",contentType:"application/json",data:JSON.stringify({new_password:a})}).done(function(){alert("Passwort geaendert!")}).fail(function(e){alert(e.responseJSON?e.responseJSON.error:"Fehler")})},$("#user-select").change(function(){var e=$(this).val();$(".folder-cb").prop("checked",!1),e&&$.get("/api/admin/assign?user_id="+e).done(function(e){e.forEach(function(e){$('.folder-cb[value="'+e+'"]').prop("checked",!0)})})}),$("#save-assignments").click(function(){var e=$("#user-select").val();if(!e)return alert("Bitte Nutzer waehlen");var n=[];$(".folder-cb:checked").each(function(){n.push($(this).val())}),$.ajax({url:"/api/admin/assign",type:"POST",contentType:"application/json",data:JSON.stringify({user_id:e,folders:n})}).done(function(){$("#assign-status").text("Gespeichert!").fadeIn().delay(2e3).fadeOut()}).fail(function(){alert("Fehler beim Speichern")})}),$("#admin-pw-form").submit(function(e){e.preventDefault(),$.post("/api/auth/change-password",{old_password:$("#admin-pw-old").val(),new_password:$("#admin-pw-new").val()}).done(function(){alert("Passwort geaendert!"),$("#admin-pw-old, #admin-pw-new").val("")}).fail(function(e){alert(e.responseJSON?e.responseJSON.error:"Fehler")})})});
|
$(document).ready(function(){function e(){$.get("/api/admin/users").done(function(e){$("#users-tbody").empty(),$("#user-select").html('<option value="">Nutzer waehlen...</option>'),e&&0!==e.length?e.forEach(function(e){var n=e.role||"unbekannt",t='<span class="badge badge-'+n+'">'+n+"</span>",a=e.created_at?new Date(e.created_at).toLocaleDateString("de-DE"):"-";if("client"===n&&e.expires_at){var r=new Date(e.expires_at).toLocaleDateString("de-DE");e.expired?(t='<span class="badge badge-expired">abgelaufen</span>',a="Abgelaufen: "+r):a="Bis: "+r}var s='<button class="btn-small" onclick="changePassword('+e.id+", '"+e.username.replace(/'/g,"\\'")+"')\">PW</button>";s+='<button class="btn-small" onclick="deleteUser('+e.id+", '"+e.username.replace(/'/g,"\\'")+"')\">X</button>",$("#users-tbody").append("<tr><td>"+e.id+"</td><td>"+e.username+" "+t+"</td><td>"+n+"</td><td>"+a+"</td><td>"+s+"</td></tr>"),"admin"!==n&&$("#user-select").append('<option value="'+e.id+'">'+e.username+" ("+n+")</option>")}):$("#users-tbody").html('<tr><td colspan="5" style="text-align:center;">Keine Nutzer gefunden</td></tr>')}).fail(function(e){var n="HTTP "+e.status+": "+e.statusText;$("#users-tbody").html('<tr><td colspan="5" style="color:#e44d26;">Fehler beim Laden: '+n+"</td></tr>")})}$.get("/api/auth/me").done(function(n){"admin"!==n.role?(alert("Kein Zugriff!"),window.location.href="/"):(e(),$.get("/api/admin/folders").done(function(e){$("#folder-checkboxes").empty(),0!==e.length?e.forEach(function(e){$("#folder-checkboxes").append('<div class="folder-check"><label><input type="checkbox" value="'+e+'" class="folder-cb"/> <i class="fa fa-folder"></i> '+e+"</label></div>")}):$("#folder-checkboxes").html("<p>Keine Unterordner in Websitebilder gefunden. Erstelle Ordner in Nextcloud.</p>")}),$("body").removeClass("is-preload"))}).fail(function(){window.location.href="/"}),$("#logout-btn").click(function(e){e.preventDefault(),$.post("/api/auth/logout").done(function(){window.location.href="/"})}),$("#create-user-form").submit(function(n){n.preventDefault();var t=$("#new-username").val().trim(),a=$("#new-password").val(),r=$("#new-role").val();t&&a?$.ajax({url:"/api/admin/users",type:"POST",contentType:"application/json",data:JSON.stringify({username:t,password:a,role:r})}).done(function(n){alert('Nutzer "'+t+'" erfolgreich erstellt!'),$("#new-username").val(""),$("#new-password").val(""),e()}).fail(function(e){var n="Unbekannter Fehler";e.responseJSON&&e.responseJSON.error?n=e.responseJSON.error:e.status&&(n="HTTP "+e.status+": "+e.statusText),alert("Fehler beim Erstellen: "+n)}):alert("Bitte Username und Passwort eingeben.")}),window.deleteUser=function(n,t){confirm('Nutzer "'+t+'" wirklich loeschen?')&&$.ajax({url:"/api/admin/users/"+n,type:"DELETE"}).done(e).fail(function(e){alert(e.responseJSON?e.responseJSON.error:"Fehler")})},window.changePassword=function(e,n){var t=prompt('Neues Passwort fuer "'+n+'":');t&&$.ajax({url:"/api/admin/users/"+e+"/password",type:"PUT",contentType:"application/json",data:JSON.stringify({new_password:t})}).done(function(){alert("Passwort geaendert!")}).fail(function(e){alert(e.responseJSON?e.responseJSON.error:"Fehler")})},$("#user-select").change(function(){var e=$(this).val();$(".folder-cb").prop("checked",!1),e&&$.get("/api/admin/assign?user_id="+e).done(function(e){e.forEach(function(e){$('.folder-cb[value="'+e+'"]').prop("checked",!0)})})}),$("#save-assignments").click(function(){var e=$("#user-select").val();if(!e)return alert("Bitte Nutzer waehlen");var n=[];$(".folder-cb:checked").each(function(){n.push($(this).val())}),$.ajax({url:"/api/admin/assign",type:"POST",contentType:"application/json",data:JSON.stringify({user_id:e,folders:n})}).done(function(){$("#assign-status").text("Gespeichert!").fadeIn().delay(2e3).fadeOut()}).fail(function(){alert("Fehler beim Speichern")})}),$("#admin-pw-form").submit(function(e){e.preventDefault(),$.post("/api/auth/change-password",{old_password:$("#admin-pw-old").val(),new_password:$("#admin-pw-new").val()}).done(function(){alert("Passwort geaendert!"),$("#admin-pw-old, #admin-pw-new").val("")}).fail(function(e){alert(e.responseJSON?e.responseJSON.error:"Fehler")})})});
|
||||||
@@ -164,7 +164,14 @@ app.get('/images/fulls/', (req, res) => {
|
|||||||
|
|
||||||
app.get('/api/admin/users', requireAdmin, (req, res) => {
|
app.get('/api/admin/users', requireAdmin, (req, res) => {
|
||||||
db.all('SELECT id, username, role, created_at FROM users', (err, rows) => {
|
db.all('SELECT id, username, role, created_at FROM users', (err, rows) => {
|
||||||
if (err) return res.json([]);
|
if (err) {
|
||||||
|
console.error('User-Abfrage fehlgeschlagen:', err.message);
|
||||||
|
// Fallback: einfache Abfrage ohne neue Spalten
|
||||||
|
return db.all('SELECT * FROM users', (err2, rows2) => {
|
||||||
|
if (err2) return res.status(500).json({ error: 'DB Error: ' + err2.message });
|
||||||
|
res.json(rows2.map(u => ({ id: u.id, username: u.username, role: u.role || 'client', created_at: u.created_at || null })));
|
||||||
|
});
|
||||||
|
}
|
||||||
// Ablaufdatum berechnen fuer Clients
|
// Ablaufdatum berechnen fuer Clients
|
||||||
const result = rows.map(u => {
|
const result = rows.map(u => {
|
||||||
const out = { ...u };
|
const out = { ...u };
|
||||||
|
|||||||
Reference in New Issue
Block a user