Add group management and owner/group dropdowns in permission editor
Backend: - _list_groups(): reads /etc/group, returns groups with gid >= 1000 plus a small whitelist (root, staff, sambashare, www-data) - GET/POST /api/groups: list and create groups (groupadd) - DELETE /api/groups/<name>: delete group (groupdel) - POST /api/groups/<name>/members: add user to group (gpasswd -a) - DELETE /api/groups/<name>/members/<user>: remove user (gpasswd -d) Frontend: - Users tab now has a Groups section: table with GID, member badges with × remove buttons, per-row "add member" select populated with users not already in the group, delete group button - loadUsers() caches result in _cachedUsers for groups table to use - openEditModal is now async; fetches /api/users + /api/groups before rendering so Owner and Group inputs have datalist autocomplete Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
302a5cb023
commit
596365b805
5 files changed
+227
-11
No files matched your search
+16
-4
@@ -100,22 +100,35 @@ async function addNFSShare() {
|
||||
|
||||
let _editCtx = null;
|
||||
|
||||
function openEditModal(type, share) {
|
||||
async function openEditModal(type, share) {
|
||||
_editCtx = { type, original: share };
|
||||
document.getElementById('editModalTitle').textContent =
|
||||
type === 'smb' ? `Edit SMB Share — ${esc(share.name)}` : `Edit NFS Export — ${esc(share.path)}`;
|
||||
document.getElementById('editModalBody').innerHTML =
|
||||
`<div style="color:var(--muted); padding:.5rem 0">Loading…</div>`;
|
||||
new bootstrap.Modal(document.getElementById('editModal')).show();
|
||||
|
||||
const [ur, gr] = await Promise.all([apiFetch('/api/users'), apiFetch('/api/groups')]);
|
||||
const users = ur ? await ur.json() : [];
|
||||
const groups = gr ? await gr.json() : [];
|
||||
|
||||
const ownerOptions = ['root', ...users.map(u => u.name)]
|
||||
.map(n => `<option value="${esc(n)}">`).join('');
|
||||
const groupOptions = groups.map(g => `<option value="${esc(g.name)}">`).join('');
|
||||
|
||||
const permSection = `
|
||||
<datalist id="ownerList">${ownerOptions}</datalist>
|
||||
<datalist id="groupList">${groupOptions}</datalist>
|
||||
<hr style="border-color:var(--border); margin:1.25rem 0 1rem">
|
||||
<div class="fw-semibold mb-3" style="font-size:.9rem; color:var(--text)">Folder Permissions</div>
|
||||
<div class="row g-2 mb-3">
|
||||
<div class="col-5">
|
||||
<label class="form-label" style="color:var(--muted); font-size:.85rem">Owner</label>
|
||||
<input type="text" id="editOwner" class="form-control" value="${esc(share.owner || '')}" placeholder="root">
|
||||
<input type="text" id="editOwner" class="form-control" value="${esc(share.owner || '')}" placeholder="root" list="ownerList">
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<label class="form-label" style="color:var(--muted); font-size:.85rem">Group</label>
|
||||
<input type="text" id="editGroup" class="form-control" value="${esc(share.group || '')}" placeholder="root">
|
||||
<input type="text" id="editGroup" class="form-control" value="${esc(share.group || '')}" placeholder="root" list="groupList">
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<label class="form-label" style="color:var(--muted); font-size:.85rem">Mode</label>
|
||||
@@ -167,7 +180,6 @@ function openEditModal(type, share) {
|
||||
}
|
||||
|
||||
document.getElementById('editModalBody').innerHTML = body;
|
||||
new bootstrap.Modal(document.getElementById('editModal')).show();
|
||||
}
|
||||
|
||||
async function submitEdit() {
|
||||
|
||||
Reference in new issue
Block a user