mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-28 16:09:17 +00:00
feat(web): add password setup page, change password, and settings tabs
- First-time visitors see a password setup page instead of open access - Password persisted to SQLite (env var DBX_PASSWORD takes priority) - Add change password in settings dialog (Security tab, web only) - Split settings dialog into Editor and Security tabs - Argon2 hashing for all password storage
This commit is contained in:
@@ -49,6 +49,10 @@ const SCHEMA_STATEMENTS: &[&str] = &[
|
||||
id INTEGER PRIMARY KEY CHECK (id = 1),
|
||||
layout_json TEXT NOT NULL
|
||||
)",
|
||||
"CREATE TABLE IF NOT EXISTS app_settings (
|
||||
id INTEGER PRIMARY KEY CHECK (id = 1),
|
||||
settings_json TEXT NOT NULL
|
||||
)",
|
||||
];
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -182,6 +186,36 @@ impl Storage {
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// App Settings
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
impl Storage {
|
||||
pub async fn save_password_hash(&self, hash: &str) -> Result<(), String> {
|
||||
let json = serde_json::json!({ "password_hash": hash }).to_string();
|
||||
sqlx::query("INSERT OR REPLACE INTO app_settings (id, settings_json) VALUES (1, ?)")
|
||||
.bind(&json)
|
||||
.execute(&self.db)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn load_password_hash(&self) -> Result<Option<String>, String> {
|
||||
let row: Option<(String,)> = sqlx::query_as("SELECT settings_json FROM app_settings WHERE id = 1")
|
||||
.fetch_optional(&self.db)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
match row {
|
||||
Some((json,)) => {
|
||||
let v: serde_json::Value = serde_json::from_str(&json).map_err(|e| e.to_string())?;
|
||||
Ok(v.get("password_hash").and_then(|v| v.as_str()).map(|s| s.to_string()))
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// AI Conversations
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user