espid2sensor: Passwort-Reset-Modal statt Browser-prompt(), Absturz bei Nicht-Admin-Login behoben
- Ersetzt window.prompt() für den Passwort-Reset in der User-Liste durch ein eigenes, zum bestehenden Bestätigungs-Modal passendes Popup (showInputModal), analog zum vorhandenen showModal für Löschbestätigungen. - Behebt ReferenceError beim Login als Nicht-Admin: userCancelBtn wurde als impliziter globaler Bezeichner referenziert statt über document.getElementById, existiert aber nur im admin-only User-Tab-HTML. Für Nicht-Admins riss das den kompletten Setup-Block (Tabs, Liste laden) ab.
This commit is contained in:
@@ -112,6 +112,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const tableBody = document.querySelector('#entriesTable tbody');
|
||||
const tabInput = document.getElementById('tabInput');
|
||||
const tabList = document.getElementById('tabList');
|
||||
const cancelBtn = document.getElementById('cancelBtn');
|
||||
const userCancelBtn = document.getElementById('userCancelBtn');
|
||||
|
||||
|
||||
// Modal für Fehleranzeige
|
||||
@@ -175,6 +177,73 @@ function showModal(message, showCancelButton, callback) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Modal für Passwort-Eingabe (z.B. Passwort-Reset aus der User-Liste)
|
||||
function showInputModal(message, callback) {
|
||||
document.querySelectorAll('.custom-modal-popup').forEach(m => m.remove());
|
||||
|
||||
let modal = document.createElement('div');
|
||||
modal.className = 'custom-modal-popup';
|
||||
|
||||
let box = document.createElement('div');
|
||||
box.className = 'custom-modal-box';
|
||||
|
||||
let msg = document.createElement('div');
|
||||
msg.className = 'custom-modal-msg';
|
||||
msg.textContent = message;
|
||||
box.appendChild(msg);
|
||||
|
||||
let input = document.createElement('input');
|
||||
input.type = 'password';
|
||||
input.className = 'custom-modal-input';
|
||||
box.appendChild(input);
|
||||
|
||||
let btndiv = document.createElement('div');
|
||||
btndiv.className = 'twobuttons';
|
||||
|
||||
const close = () => {
|
||||
if (modal.parentNode) modal.parentNode.removeChild(modal);
|
||||
};
|
||||
|
||||
let btnCancel = document.createElement('button');
|
||||
btnCancel.className = 'custom-modal-btn';
|
||||
btnCancel.textContent = 'Abbruch';
|
||||
btnCancel.onclick = () => {
|
||||
close();
|
||||
callback(null);
|
||||
};
|
||||
btndiv.appendChild(btnCancel);
|
||||
|
||||
let btnOk = document.createElement('button');
|
||||
btnOk.className = 'custom-modal-btn';
|
||||
btnOk.textContent = 'OK';
|
||||
btnOk.onclick = () => {
|
||||
const value = input.value;
|
||||
close();
|
||||
callback(value || null);
|
||||
};
|
||||
btndiv.appendChild(btnOk);
|
||||
|
||||
box.appendChild(btndiv);
|
||||
modal.appendChild(box);
|
||||
document.body.appendChild(modal);
|
||||
input.focus();
|
||||
|
||||
input.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
btnOk.click();
|
||||
}
|
||||
});
|
||||
|
||||
modal.onclick = (e) => {
|
||||
if (e.target === modal) {
|
||||
close();
|
||||
callback(null);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Sensornummer nur Zahlen erlauben
|
||||
sensorNumberInput.addEventListener('input', () => {
|
||||
sensorNumberInput.value = sensorNumberInput.value.replace(/\D/g, '');
|
||||
@@ -464,21 +533,22 @@ function showModal(message, showCancelButton, callback) {
|
||||
});
|
||||
|
||||
document.querySelectorAll('.resetUserBtn').forEach(btn => {
|
||||
btn.addEventListener('click', async () => {
|
||||
btn.addEventListener('click', () => {
|
||||
const email = btn.getAttribute('data-email');
|
||||
const newPassword = prompt(`Neues Passwort für ${email}:`);
|
||||
if (!newPassword) return;
|
||||
try {
|
||||
const res = await fetch('/api/resetPassword', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, newPassword })
|
||||
});
|
||||
const data = await res.json();
|
||||
usersResult.textContent = data.success ? `Passwort für ${email} zurückgesetzt.` : (data.error || 'Fehler beim Zurücksetzen.');
|
||||
} catch (err) {
|
||||
usersResult.textContent = 'Serverfehler.';
|
||||
}
|
||||
showInputModal(`Neues Passwort für ${email}:`, async (newPassword) => {
|
||||
if (!newPassword) return;
|
||||
try {
|
||||
const res = await fetch('/api/resetPassword', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, newPassword })
|
||||
});
|
||||
const data = await res.json();
|
||||
usersResult.textContent = data.success ? `Passwort für ${email} zurückgesetzt.` : (data.error || 'Fehler beim Zurücksetzen.');
|
||||
} catch (err) {
|
||||
usersResult.textContent = 'Serverfehler.';
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -510,7 +580,7 @@ function showModal(message, showCancelButton, callback) {
|
||||
saveBtn.addEventListener('click', saveEntry);
|
||||
refreshBtn.addEventListener('click', loadEntries);
|
||||
cancelBtn.addEventListener('click', () => clearForm(true));
|
||||
userCancelBtn.addEventListener('click', () => clearUserForm(true));
|
||||
if (userCancelBtn) userCancelBtn.addEventListener('click', () => clearUserForm(true));
|
||||
|
||||
tabInput.addEventListener('click', () => showTab('input'))
|
||||
tabList.addEventListener('click', () => showTab('list'))
|
||||
|
||||
@@ -56,6 +56,12 @@
|
||||
color: red;
|
||||
}
|
||||
|
||||
.custom-modal-input {
|
||||
display: block;
|
||||
width: 80%;
|
||||
margin: 0 auto 1.5rem auto;
|
||||
}
|
||||
|
||||
.custom-modal-btn {
|
||||
padding: 0.8rem 2.5rem;
|
||||
font-size: 1.1rem;
|
||||
|
||||
Reference in New Issue
Block a user