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:
@@ -327,6 +327,32 @@ pub async fn set_active(pool: &SqlitePool, id: &str, active: bool) -> Result<()>
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Changes the role assignment and optionally the display name in one statement.
|
||||
pub async fn update_profile(
|
||||
pool: &SqlitePool,
|
||||
id: &str,
|
||||
username: &str,
|
||||
display_name: Option<&str>,
|
||||
role_id: &str,
|
||||
) -> Result<()> {
|
||||
let n = sqlx::query(
|
||||
"UPDATE users
|
||||
SET username = ?2, display_name = ?3, role_id = ?4, updated_at = datetime('now')
|
||||
WHERE id = ?1",
|
||||
)
|
||||
.bind(id)
|
||||
.bind(username)
|
||||
.bind(display_name)
|
||||
.bind(role_id)
|
||||
.execute(pool)
|
||||
.await?
|
||||
.rows_affected();
|
||||
if n == 0 {
|
||||
bail!("no such user: {id}");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn rename(pool: &SqlitePool, id: &str, username: &str, display_name: Option<&str>) -> Result<()> {
|
||||
let n = sqlx::query(
|
||||
"UPDATE users SET username = ?2, display_name = ?3, updated_at = datetime('now')
|
||||
|
||||
Reference in New Issue
Block a user