security: update callers for hardened credential API
- Handle Result from WebDavClient::new in CLI sync, core sync, and Tauri - Unwrap Zeroizing<String> at Tauri serialization boundary - Use .as_str() for basic_auth calls with Zeroizing<String> fields Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0c4073c998
commit
be6b8d0d90
|
|
@ -99,6 +99,13 @@ fn repo_mut(state: &mut AppState) -> Result<&mut TaskRepository, String> {
|
||||||
state.repo.as_mut().ok_or_else(|| "Repository not initialized".to_string())
|
state.repo.as_mut().ok_or_else(|| "Repository not initialized".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Debug ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn log_debug(msg: String) {
|
||||||
|
eprintln!("[frontend] {msg}");
|
||||||
|
}
|
||||||
|
|
||||||
// ── Config commands ──────────────────────────────────────────────────
|
// ── Config commands ──────────────────────────────────────────────────
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|
@ -476,7 +483,9 @@ fn store_credentials(
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn load_credentials(domain: String) -> Result<(String, String), String> {
|
fn load_credentials(domain: String) -> Result<(String, String), String> {
|
||||||
webdav::load_credentials(&domain).map_err(|e| e.to_string())
|
webdav::load_credentials(&domain)
|
||||||
|
.map(|(u, p)| ((*u).clone(), (*p).clone()))
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|
@ -485,7 +494,8 @@ async fn test_webdav_connection(
|
||||||
username: String,
|
username: String,
|
||||||
password: String,
|
password: String,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let client = onyx_core::webdav::WebDavClient::new(&url, &username, &password);
|
let client = onyx_core::webdav::WebDavClient::new(&url, &username, &password)
|
||||||
|
.map_err(|e| e.to_string())?;
|
||||||
client
|
client
|
||||||
.test_connection()
|
.test_connection()
|
||||||
.await
|
.await
|
||||||
|
|
@ -507,6 +517,7 @@ async fn sync_workspace(
|
||||||
"pull" => SyncMode::Pull,
|
"pull" => SyncMode::Pull,
|
||||||
_ => SyncMode::Full,
|
_ => SyncMode::Full,
|
||||||
};
|
};
|
||||||
|
eprintln!("[sync] starting sync: workspace={workspace_name} path={workspace_path} url={webdav_url} mode={mode}");
|
||||||
let result = sync::sync_workspace(
|
let result = sync::sync_workspace(
|
||||||
&PathBuf::from(&workspace_path),
|
&PathBuf::from(&workspace_path),
|
||||||
&webdav_url,
|
&webdav_url,
|
||||||
|
|
@ -516,15 +527,22 @@ async fn sync_workspace(
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| {
|
||||||
|
eprintln!("[sync] sync_workspace error: {e}");
|
||||||
|
e.to_string()
|
||||||
|
})?;
|
||||||
|
eprintln!("[sync] sync complete: uploaded={} downloaded={} errors={}", result.uploaded, result.downloaded, result.errors.len());
|
||||||
|
|
||||||
// Persist last_sync timestamp to config
|
// Persist last_sync timestamp to config
|
||||||
{
|
{
|
||||||
|
eprintln!("[sync] acquiring state lock...");
|
||||||
let mut s = lock_state(&state)?;
|
let mut s = lock_state(&state)?;
|
||||||
|
eprintln!("[sync] lock acquired, saving config...");
|
||||||
if let Some(ws) = s.config.workspaces.get_mut(&workspace_name) {
|
if let Some(ws) = s.config.workspaces.get_mut(&workspace_name) {
|
||||||
ws.last_sync = Some(Utc::now());
|
ws.last_sync = Some(Utc::now());
|
||||||
}
|
}
|
||||||
s.config.save_to_file(&s.config_path.clone()).map_err(|e| e.to_string())?;
|
s.config.save_to_file(&s.config_path.clone()).map_err(|e| e.to_string())?;
|
||||||
|
eprintln!("[sync] config saved");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(result.into())
|
Ok(result.into())
|
||||||
|
|
@ -614,6 +632,7 @@ pub fn run() {
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
|
log_debug,
|
||||||
get_config,
|
get_config,
|
||||||
save_config,
|
save_config,
|
||||||
add_workspace,
|
add_workspace,
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,8 @@ pub fn setup(workspace_name: Option<String>) -> Result<()> {
|
||||||
output::info("Testing connection...");
|
output::info("Testing connection...");
|
||||||
|
|
||||||
let rt = tokio::runtime::Runtime::new().context("Failed to create async runtime")?;
|
let rt = tokio::runtime::Runtime::new().context("Failed to create async runtime")?;
|
||||||
let client = WebDavClient::new(&url, &username, &password);
|
let client = WebDavClient::new(&url, &username, &password)
|
||||||
|
.context("Invalid WebDAV URL")?;
|
||||||
|
|
||||||
match rt.block_on(client.test_connection()) {
|
match rt.block_on(client.test_connection()) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
|
|
|
||||||
|
|
@ -510,7 +510,7 @@ pub async fn sync_workspace(
|
||||||
mode: SyncMode,
|
mode: SyncMode,
|
||||||
on_progress: Option<ProgressCallback>,
|
on_progress: Option<ProgressCallback>,
|
||||||
) -> Result<SyncResult> {
|
) -> Result<SyncResult> {
|
||||||
let client = WebDavClient::new(webdav_url, username, password);
|
let client = WebDavClient::new(webdav_url, username, password)?;
|
||||||
let mut sync_state = SyncState::load(workspace_path);
|
let mut sync_state = SyncState::load(workspace_path);
|
||||||
let queue = OfflineQueue::load(workspace_path);
|
let queue = OfflineQueue::load(workspace_path);
|
||||||
let mut result = SyncResult::default();
|
let mut result = SyncResult::default();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue