fix: harden auth and fix frontend issues
- Add builtin admin user with full access, immutable permissions (lib/db.py, lib/auth_users.py, webui/static/pages/users.js) - Fix passkeys TypeError on string throws (webui/static/pages/passkeys.js) - Add zero-permission warning in create user modal (webui/static/pages/users.js) - Restore readonly on proxy paths textarea (webui/static/pages/proxy.js) - Mask credential ownership errors to prevent enumeration (lib/webauthn.py, tests/test_auth.py)
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
import { h, definePage, reactive } from '/static/hoover/index.js';
|
||||
import { html, PageHeader, Table, Badge, ConfirmDelete, Empty, Card, openModal, closeModal, formModal, apiFetch, toast, esc } from '/static/hoover/index.js';
|
||||
|
||||
const BUILTIN_ADMIN = 'admin';
|
||||
|
||||
const SUBSYSTEMS = [
|
||||
{ key: 'firewall', label: 'Firewall' },
|
||||
{ key: 'network', label: 'Network' },
|
||||
@@ -157,11 +159,16 @@ function openEditPermissionsModal(user) {
|
||||
for (const sub of SUBSYSTEMS) {
|
||||
const level = document.getElementById('edit-perm-' + sub.key).value;
|
||||
if (level && level !== '—') {
|
||||
perms[sub.key] = level;
|
||||
perms[sub.key] = level;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const res = await apiFetch('/api/auth/users/' + encodeURIComponent(user.username), {
|
||||
if (user.username === BUILTIN_ADMIN) {
|
||||
toast('Cannot modify permissions for builtin admin', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const res = await apiFetch('/api/auth/users/' + encodeURIComponent(user.username), {
|
||||
method: 'POST',
|
||||
body: { permissions: perms },
|
||||
});
|
||||
@@ -215,7 +222,8 @@ function UsersPage() {
|
||||
<td class="text-sm">${u.credCount || 0}</td>
|
||||
<td class="text-sm text-muted">${permBadges.length ? permBadges.join(' ') : '—'}</td>
|
||||
<td>
|
||||
<button class="btn btn-sm btn-outline" onClick=${() => openEditPermissionsModal(u)}>Edit</button>
|
||||
${u.username === BUILTIN_ADMIN ? html`<span class="text-muted text-sm">(builtin)</span>` :
|
||||
html`<button class="btn btn-sm btn-outline" onClick=${() => openEditPermissionsModal(u)}>Edit</button>`}
|
||||
${isMe ? html`<span class="text-muted text-sm">(you)</span>` :
|
||||
html`<${ConfirmDelete}
|
||||
url=${'/api/auth/users/' + encodeURIComponent(u.username)}
|
||||
|
||||
Reference in New Issue
Block a user