feat(auth): login, roles, user mgmt, setup wizard, and session guard
- New skald-setup crate: interactive first-run wizard that creates the admin user, prompts for encryption choice and password - Auth system: session-based login/logout with cookie, guard middleware - Roles API: CRUD for data-driven roles, seeded on first boot - Users management API: create, list, edit, delete users - Setup state API: check if first admin has been created - Frontend: login-page, setup-page, users-page, roles-page, profile-page components with corresponding CSS - Topbar: avatar dropdown with profile link and logout - Sidebar: nav entries for Users and Roles (admin only) - Page shell CSS: layout support for the new pages - build.sh: builds both skald and skald-setup binaries - run.sh: runs skald-setup before the server loop - CLAUDE.md: updated workspace layout and build/run docs
This commit is contained in:
@@ -106,7 +106,7 @@ export class AppSidebar extends LightElement {
|
||||
// Segment ends at the first `/` (e.g. `#session/123`) or `?` (e.g. `#file_viewer?path=...`).
|
||||
const match = hash.match(/^([^/?]+)/);
|
||||
const segment = match ? match[1] : '';
|
||||
return ['inbox', 'tasks', 'projects', 'models', 'providers', 'approval', 'agents', 'config', 'llm-requests', 'session', 'tic', 'file_viewer'].includes(segment) ? segment : 'home';
|
||||
return ['inbox', 'tasks', 'projects', 'models', 'providers', 'approval', 'agents', 'users', 'roles', 'profile', 'config', 'llm-requests', 'session', 'tic', 'file_viewer'].includes(segment) ? segment : 'home';
|
||||
}
|
||||
|
||||
_tasksSectionFromHash() {
|
||||
@@ -276,6 +276,16 @@ export class AppSidebar extends LightElement {
|
||||
<i class="bi bi-people"></i>
|
||||
<span class="sidebar-link-name">Agents</span>
|
||||
</a>
|
||||
<a href="#" class="sidebar-link ${this._activePage === 'users' ? 'active' : ''}"
|
||||
@click=${(e) => this._togglePage('users', e)}>
|
||||
<i class="bi bi-person-badge"></i>
|
||||
<span class="sidebar-link-name">Users</span>
|
||||
</a>
|
||||
<a href="#" class="sidebar-link ${this._activePage === 'roles' ? 'active' : ''}"
|
||||
@click=${(e) => this._togglePage('roles', e)}>
|
||||
<i class="bi bi-tags"></i>
|
||||
<span class="sidebar-link-name">Roles</span>
|
||||
</a>
|
||||
<a href="#" class="sidebar-link ${this._activePage === 'config' ? 'active' : ''}"
|
||||
@click=${(e) => this._togglePage('config', e)}>
|
||||
<i class="bi bi-gear"></i>
|
||||
|
||||
Reference in New Issue
Block a user