Remove user rename feature; add www-data hint in WebDAV edit modal
- Removed PATCH /api/users/<name> route (rename_user) - Removed renameModal from index.html - Removed openRenameModal/submitRename from users.js - Removed Rename button from users table - Removed rename docs from README - Added green info box in WebDAV edit modal: set group=www-data, mode=775 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
f081496b4b
commit
b6179865b5
5 files changed
+5
-70
No files matched your search
@@ -111,8 +111,6 @@ All routes require a login session. On first run you are redirected to `/setup`
|
||||
|
||||
Users created in MicroNAS are standard Linux system accounts (`useradd -M -s /usr/sbin/nologin`). Their password is set in both the Linux shadow file (via `smbpasswd`) and the WebDAV htpasswd file automatically.
|
||||
|
||||
**Rename** — the Rename button in the Users tab renames the Linux account (`usermod -l`). Because SMB and WebDAV store passwords by username, those entries are removed and must be reset after a rename. The UI shows a warning prompt.
|
||||
|
||||
**Delete** — removes the Linux account, SMB entry, and WebDAV htpasswd entry.
|
||||
|
||||
**Password change** — updates SMB and WebDAV passwords in sync. Changing a user's password also re-registers them in WebDAV if they were created before WebDAV was installed.
|
||||
|
||||
@@ -936,27 +936,6 @@ def change_admin_credentials():
|
||||
return jsonify({'status': 'updated'})
|
||||
|
||||
|
||||
@app.route('/api/users/<name>', methods=['PATCH'])
|
||||
@require_auth
|
||||
def rename_user(name):
|
||||
if not VALID_NAME.match(name):
|
||||
return jsonify({'error': 'invalid username'}), 400
|
||||
new_name = (request.json or {}).get('name', '').strip()
|
||||
if not new_name or not VALID_NAME.match(new_name):
|
||||
return jsonify({'error': 'invalid new username'}), 400
|
||||
if new_name == name:
|
||||
return jsonify({'status': 'no change'}), 200
|
||||
|
||||
r = subprocess.run(['usermod', '-l', new_name, name], capture_output=True, text=True)
|
||||
if r.returncode != 0:
|
||||
return jsonify({'error': r.stderr.strip() or 'usermod failed'}), 500
|
||||
|
||||
# Remove SMB and WebDAV entries — password must be reset after rename
|
||||
subprocess.run(['smbpasswd', '-x', name], capture_output=True)
|
||||
_remove_webdav_user(name)
|
||||
return jsonify({'status': 'renamed',
|
||||
'warning': 'SMB and WebDAV password must be reset for the renamed user.'})
|
||||
|
||||
|
||||
@app.route('/api/users/<name>/password', methods=['POST'])
|
||||
@require_auth
|
||||
|
||||
@@ -259,6 +259,11 @@ async function openEditModal(type, share) {
|
||||
</label>
|
||||
<input type="text" id="editWebdavUsers" class="form-control" value="${esc(share.users || '')}">
|
||||
</div>
|
||||
<div class="mb-3 px-2 py-2 rounded" style="background:#1a2a1a; border:1px solid #2d4a2d; font-size:.82rem; color:#8dba8d">
|
||||
WebDAV writes files as <code style="color:#3fb950">www-data</code>.
|
||||
Set the folder group to <code style="color:#3fb950">www-data</code> and mode to <code style="color:#3fb950">775</code> below,
|
||||
or add <code style="color:#3fb950">www-data</code> to your share group.
|
||||
</div>
|
||||
${permSection}`;
|
||||
} else {
|
||||
const isRo = /\(ro[,)]/.test(share.clients);
|
||||
|
||||
@@ -22,8 +22,6 @@ async function loadUsers() {
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button class="btn btn-sm me-1" style="border:1px solid var(--border); color:var(--muted)"
|
||||
onclick="openRenameModal(${nameJson})">Rename</button>
|
||||
<button class="btn btn-sm me-1" style="border:1px solid var(--border); color:var(--muted)"
|
||||
onclick="openPwModal(${nameJson})">Password</button>
|
||||
<button class="btn btn-sm btn-danger"
|
||||
@@ -97,30 +95,6 @@ async function submitPassword() {
|
||||
showToast(`Password updated for "${name}".`);
|
||||
}
|
||||
|
||||
function openRenameModal(name) {
|
||||
document.getElementById('renameOldName').value = name;
|
||||
document.getElementById('renameNewName').value = name;
|
||||
new bootstrap.Modal(document.getElementById('renameModal')).show();
|
||||
}
|
||||
|
||||
async function submitRename() {
|
||||
const oldName = document.getElementById('renameOldName').value;
|
||||
const newName = document.getElementById('renameNewName').value.trim();
|
||||
if (!newName) return showToast('New username is required.', 'danger');
|
||||
|
||||
const res = await apiFetch(`/api/users/${encodeURIComponent(oldName)}`, {
|
||||
method: 'PATCH', headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({name: newName}),
|
||||
});
|
||||
if (!res) return;
|
||||
const data = await res.json();
|
||||
bootstrap.Modal.getInstance(document.getElementById('renameModal')).hide();
|
||||
if (!res.ok) return showToast('Error: ' + (data.error || res.status), 'danger');
|
||||
if (data.warning) showToast(data.warning, 'warning');
|
||||
else showToast(`Renamed to "${newName}".`);
|
||||
loadUsers();
|
||||
loadGroups();
|
||||
}
|
||||
|
||||
function openAdminSettings() {
|
||||
document.getElementById('adminCurrentPw').value = '';
|
||||
|
||||
@@ -102,27 +102,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Rename user modal -->
|
||||
<div class="modal fade" id="renameModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Rename User</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<input type="hidden" id="renameOldName">
|
||||
<label class="form-label" style="color:var(--muted); font-size:.85rem">New Username</label>
|
||||
<input type="text" id="renameNewName" class="form-control mb-2">
|
||||
<div class="small" style="color:var(--yellow)">SMB and WebDAV password must be reset after rename.</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="button" class="btn btn-primary btn-sm" onclick="submitRename()">Rename</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Header -->
|
||||
<div class="topbar d-flex justify-content-between align-items-center">
|
||||
|
||||
Reference in new issue
Block a user