feat: admin reset password and set quota for existing mailboxes

- Add Reset PW and Set Quota action buttons to each mailbox row
- Shared edit modal that switches between password / quota modes
- New woocow_admin_mailbox_edit AJAX handler in PHP
- Quota reloads mailbox list after save; password closes modal silently
- Customer-facing Change Password was already implemented in account JS

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-27 08:21:46 +01:00
parent 8644282ecb
commit 1ea2ed7e74
2 changed files with 164 additions and 5 deletions

View File

@@ -312,10 +312,11 @@
<th>Email</th><th>Name</th><th>Quota Used</th><th>Quota Max</th><th>Active</th><th>Actions</th>
</tr></thead><tbody>`;
boxes.forEach(m => {
const pct = m.percent_in_use || 0;
const used = formatMB(m.quota_used);
const max = formatMB(m.quota);
const bar = `<div class="woocow-quota-bar"><div style="width:${pct}%"></div></div>`;
const pct = m.percent_in_use || 0;
const used = formatMB(m.quota_used);
const max = formatMB(m.quota);
const bar = `<div class="woocow-quota-bar"><div style="width:${pct}%"></div></div>`;
const quotaMB = Math.round((m.quota || 0) / 1024 / 1024);
html += `<tr>
<td><a href="${esc(webmail)}" target="_blank">${esc(m.username)}</a></td>
<td>${esc(m.name)}</td>
@@ -323,7 +324,12 @@
<td>${max}</td>
<td>${m.active == 1 ? '✓' : ''}</td>
<td class="woocow-actions">
<button class="button button-small wc-mb-del" data-email="${esc(m.username)}" style="color:#a00">Delete</button>
<button class="button button-small wc-mb-reset-pw"
data-email="${esc(m.username)}">Reset PW</button>
<button class="button button-small wc-mb-set-quota"
data-email="${esc(m.username)}" data-quota="${quotaMB}">Set Quota</button>
<button class="button button-small wc-mb-del"
data-email="${esc(m.username)}" style="color:#a00">Delete</button>
</td>
</tr>`;
});
@@ -379,6 +385,69 @@
else notice($('#wc-mb-notices'), 'error', res.data);
});
});
// ── Edit modal: Reset PW ──────────────────────────────────────────────
let editEmail = '';
let editType = '';
const openEditModal = (email, type, currentQuota) => {
editEmail = email;
editType = type;
$('#wc-mb-edit-subtitle').text(email);
$('#wc-mb-edit-notice').text('');
$('#wc-mb-edit-pw-section, #wc-mb-edit-quota-section').hide();
if (type === 'password') {
$('#wc-mb-edit-title').text('Reset Password');
$('#wc-mb-edit-pass, #wc-mb-edit-pass2').val('');
$('#wc-mb-edit-pw-section').show();
setTimeout(() => $('#wc-mb-edit-pass').trigger('focus'), 100);
} else {
$('#wc-mb-edit-title').text('Set Quota');
$('#wc-mb-edit-quota').val(currentQuota || 1024);
$('#wc-mb-edit-quota-section').show();
setTimeout(() => $('#wc-mb-edit-quota').trigger('focus'), 100);
}
$('#wc-mb-edit-modal').show();
};
$(document).on('click', '.wc-mb-reset-pw', function () {
openEditModal($(this).data('email'), 'password', null);
});
$(document).on('click', '.wc-mb-set-quota', function () {
openEditModal($(this).data('email'), 'quota', $(this).data('quota'));
});
$('#wc-mb-edit-cancel').on('click', () => $('#wc-mb-edit-modal').hide());
$(document).on('keydown', e => { if (e.key === 'Escape') $('#wc-mb-edit-modal').hide(); });
$('#wc-mb-edit-save').on('click', () => {
const $note = $('#wc-mb-edit-notice').text('Saving…');
const data = { server_id: currentServerId, email: editEmail, type: editType };
if (editType === 'password') {
data.password = $('#wc-mb-edit-pass').val();
data.password2 = $('#wc-mb-edit-pass2').val();
if (!data.password) { $note.html('<span style="color:red">Password cannot be empty.</span>'); return; }
if (data.password !== data.password2) { $note.html('<span style="color:red">Passwords do not match.</span>'); return; }
} else {
data.quota = $('#wc-mb-edit-quota').val();
if (!data.quota || data.quota < 1) { $note.html('<span style="color:red">Enter a valid quota.</span>'); return; }
}
ajax('woocow_admin_mailbox_edit', data).done(res => {
if (res.success) {
$('#wc-mb-edit-modal').hide();
const msg = editType === 'password' ? 'Password updated.' : 'Quota updated.';
notice($('#wc-mb-notices'), 'success', `<strong>${esc(editEmail)}</strong> — ${msg}`);
if (editType === 'quota') loadMailboxes(); // refresh to show new quota
} else {
$note.html(`<span style="color:red">${esc(res.data)}</span>`);
}
});
});
}
// ── Utilities ─────────────────────────────────────────────────────────────