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:
@@ -135,6 +135,21 @@ impl UserManager {
|
||||
db::users::count(&self.system).await
|
||||
}
|
||||
|
||||
/// Verifies the password **always**, regardless of whether the pool is
|
||||
/// already unlocked. Use this for login authentication; use [`open_db`]
|
||||
/// only for pool lifecycle.
|
||||
pub async fn verify_credentials(&self, id: &str, password: &str) -> Result<(), AuthError> {
|
||||
let user = db::users::get(&self.system, id)
|
||||
.await
|
||||
.map_err(AuthError::Internal)?
|
||||
.ok_or(AuthError::UnknownUser)?;
|
||||
if !user.active {
|
||||
return Err(AuthError::Inactive);
|
||||
}
|
||||
self.authenticate(&user, Some(password)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// ── Unlock registry ───────────────────────────────────────────────────────
|
||||
|
||||
/// The user's pool, or `None` when the database is still locked (§9).
|
||||
|
||||
Reference in New Issue
Block a user