import { useState, useEffect } from 'react' import { useAuth } from '../contexts/AuthContext' import { usePermissions } from '../hooks/usePermissions' const Users = () => { const { authFetch } = useAuth() const { refreshPermissions } = usePermissions() const [users, setUsers] = useState([]) const [groups, setGroups] = useState([]) const [loading, setLoading] = useState(false) const [error, setError] = useState('') const [showForm, setShowForm] = useState(false) const [editingUser, setEditingUser] = useState(null) const [showDeleteModal, setShowDeleteModal] = useState(false) const [userToDelete, setUserToDelete] = useState(null) const [confirmChecked, setConfirmChecked] = useState(false) const [showToggleModal, setShowToggleModal] = useState(false) const [userToToggle, setUserToToggle] = useState(null) const [confirmToggleChecked, setConfirmToggleChecked] = useState(false) const [formData, setFormData] = useState({ username: '', email: '', oldPassword: '', password: '', confirmPassword: '', isAdmin: false, enabled: true, groupIds: [] }) const [showAdminWarning, setShowAdminWarning] = useState(false) useEffect(() => { fetchUsers() fetchGroups() }, []) const fetchUsers = async () => { try { setError('') const response = await authFetch('/api/users') if (response.ok) { const data = await response.json() setUsers(Array.isArray(data) ? data : []) } else { setError('Fehler beim Abrufen der Benutzer') } } catch (err) { setError('Fehler beim Abrufen der Benutzer') console.error('Error fetching users:', err) } } const fetchGroups = async () => { try { const response = await authFetch('/api/permission-groups') if (response.ok) { const data = await response.json() setGroups(Array.isArray(data) ? data : []) } } catch (err) { console.error('Error fetching permission groups:', err) } } const handleSubmit = async (e) => { e.preventDefault() setError('') setLoading(true) // Validierung: Passwort-Bestätigung muss übereinstimmen if (formData.password && formData.password !== formData.confirmPassword) { setError('Die Passwörter stimmen nicht überein') setLoading(false) return } // Validierung: Wenn Passwort geändert wird, muss altes Passwort vorhanden sein if (editingUser && formData.password && !formData.oldPassword) { setError('Bitte geben Sie das alte Passwort ein, um das Passwort zu ändern') setLoading(false) return } try { const url = editingUser ? `/api/users/${editingUser.id}` : '/api/users' const method = editingUser ? 'PUT' : 'POST' const body = editingUser ? { // Username/Email nur setzen wenn nicht der spezielle Admin-User mit UID 'admin' ...(formData.username && editingUser.id !== 'admin' && { username: formData.username }), ...(formData.email && editingUser.id !== 'admin' && { email: formData.email }), ...(formData.password && { password: formData.password, oldPassword: formData.oldPassword }), // isAdmin nur setzen wenn nicht UID 'admin' (UID 'admin' ist immer Admin) ...(formData.isAdmin !== undefined && editingUser.id !== 'admin' && { isAdmin: formData.isAdmin }), // enabled wird nicht über das Bearbeitungsformular geändert, nur über den Button in der Liste ...(formData.groupIds !== undefined && { groupIds: formData.groupIds }) } : { username: formData.username, email: formData.email, password: formData.password, isAdmin: formData.isAdmin || false, enabled: true, // Neue User sind immer aktiviert, enabled kann nur für UID 'admin' geändert werden groupIds: formData.groupIds || [] } const response = await authFetch(url, { method, headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(body), }) if (response.ok) { await fetchUsers() setFormData({ username: '', email: '', oldPassword: '', password: '', confirmPassword: '', isAdmin: false, enabled: true, groupIds: [] }) setShowForm(false) setEditingUser(null) setShowAdminWarning(false) // Aktualisiere Berechtigungen nach Änderung an Benutzern (Gruppen-Zuweisungen könnten sich geändert haben) refreshPermissions() } else { const errorData = await response.json() setError(errorData.error || 'Fehler beim Speichern des Benutzers') } } catch (err) { setError('Fehler beim Speichern des Benutzers') console.error('Error saving user:', err) } finally { setLoading(false) } } const handleEdit = (user) => { setEditingUser(user) setFormData({ username: user.username, email: user.email, oldPassword: '', password: '', confirmPassword: '', isAdmin: user.isAdmin || false, enabled: user.enabled !== undefined ? user.enabled : true, // Wird nicht im Formular angezeigt, nur für internen Zustand groupIds: user.groupIds || [] }) setShowForm(true) } const handleDelete = (user) => { setUserToDelete(user) setShowDeleteModal(true) setConfirmChecked(false) } const handleToggleEnabled = (user) => { if (user.id !== 'admin') { return } setUserToToggle(user) setShowToggleModal(true) setConfirmToggleChecked(false) } const confirmToggle = async () => { if (!confirmToggleChecked || !userToToggle) { return } const newEnabled = !userToToggle.enabled const action = newEnabled ? 'aktivieren' : 'deaktivieren' try { setLoading(true) const response = await authFetch(`/api/users/${userToToggle.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ enabled: newEnabled }), }) if (response.ok) { await fetchUsers() setShowToggleModal(false) setUserToToggle(null) setConfirmToggleChecked(false) // Aktualisiere Berechtigungen nach Änderung refreshPermissions() } else { const errorData = await response.json().catch(() => ({ error: `Fehler beim ${action}` })) const errorMessage = errorData.error || `Fehler beim ${action} des Admin-Users` setError(errorMessage) // Schließe Modal bei Fehler if (response.status === 403) { setShowToggleModal(false) setUserToToggle(null) setConfirmToggleChecked(false) } } } catch (err) { console.error(`Error toggling enabled for admin user:`, err) setError(`Fehler beim ${action} des Admin-Users`) } finally { setLoading(false) } } const cancelToggle = () => { setShowToggleModal(false) setUserToToggle(null) setConfirmToggleChecked(false) } const confirmDelete = async () => { if (!confirmChecked || !userToDelete) { return } try { const response = await authFetch(`/api/users/${userToDelete.id}`, { method: 'DELETE', }) if (response.ok) { await fetchUsers() setShowDeleteModal(false) setUserToDelete(null) setConfirmChecked(false) // Aktualisiere Berechtigungen nach Löschen eines Benutzers refreshPermissions() } else { const errorData = await response.json().catch(() => ({ error: 'Fehler beim Löschen' })) const errorMessage = errorData.error || 'Fehler beim Löschen des Benutzers' // Zeige Fehlermeldung setError(errorMessage) // Wenn Admin-Löschung verhindert wurde, schließe Modal if (response.status === 403) { setShowDeleteModal(false) setUserToDelete(null) setConfirmChecked(false) } } } catch (err) { console.error('Error deleting user:', err) setError('Fehler beim Löschen des Benutzers') } } const cancelDelete = () => { setShowDeleteModal(false) setUserToDelete(null) setConfirmChecked(false) } const handleChange = (e) => { setFormData({ ...formData, [e.target.name]: e.target.value }) } const handleGroupToggle = (groupId) => { setFormData(prev => { const groupIds = prev.groupIds || [] if (groupIds.includes(groupId)) { return { ...prev, groupIds: groupIds.filter(id => id !== groupId) } } else { return { ...prev, groupIds: [...groupIds, groupId] } } }) } const handleAdminToggle = (e) => { const isAdmin = e.target.checked if (isAdmin && !showAdminWarning) { setShowAdminWarning(true) } setFormData(prev => ({ ...prev, isAdmin, // Wenn Admin aktiviert wird, entferne alle Gruppen und stelle sicher dass enabled=true groupIds: isAdmin ? [] : prev.groupIds, enabled: isAdmin ? true : (prev.enabled !== undefined ? prev.enabled : true) // Admin muss immer enabled sein })) } const getPermissionLabel = (permission) => { switch (permission) { case 'READ': return 'Lesen' case 'READ_WRITE': return 'Lesen/Schreiben' case 'FULL_ACCESS': return 'Vollzugriff' default: return permission } } return (
Verwalten Sie lokale Benutzer und deren Zugangsdaten.
{error}
Noch keine Benutzer vorhanden. Erstellen Sie Ihren ersten Benutzer!
) : ({user.email}
{!user.isAdmin && user.groupIds && user.groupIds.length > 0 && (Berechtigungsgruppen:
Erstellt: {user.createdAt ? new Date(user.createdAt).toLocaleString('de-DE') : 'Unbekannt'}
{user.id && (ID: {user.id}
)}Sie sind dabei, diesem Benutzer Administrator-Rechte zu gewähren.
⚠️ Mögliche Gefahren:
Möchten Sie wirklich fortfahren?
Möchten Sie den Benutzer {userToDelete.username} wirklich löschen?
Diese Aktion kann nicht rückgängig gemacht werden.
Möchten Sie den Admin-User {userToToggle.username} (UID: {userToToggle.id}) wirklich {userToToggle.enabled ? 'deaktivieren' : 'aktivieren'}?
{userToToggle.enabled ? 'Der Admin-User kann sich nach der Deaktivierung nicht mehr anmelden und keine API-Calls durchführen.' : 'Der Admin-User kann sich nach der Aktivierung wieder anmelden und API-Calls durchführen.'}